ztrevc.c
Go to the documentation of this file.
00001 /* ztrevc.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_b2 = {1.,0.};
00019 static integer c__1 = 1;
00020 
00021 /* Subroutine */ int ztrevc_(char *side, char *howmny, logical *select, 
00022         integer *n, doublecomplex *t, integer *ldt, doublecomplex *vl, 
00023         integer *ldvl, doublecomplex *vr, integer *ldvr, integer *mm, integer 
00024         *m, doublecomplex *work, doublereal *rwork, integer *info)
00025 {
00026     /* System generated locals */
00027     integer t_dim1, t_offset, vl_dim1, vl_offset, vr_dim1, vr_offset, i__1, 
00028             i__2, i__3, i__4, i__5;
00029     doublereal d__1, d__2, d__3;
00030     doublecomplex z__1, z__2;
00031 
00032     /* Builtin functions */
00033     double d_imag(doublecomplex *);
00034     void d_cnjg(doublecomplex *, doublecomplex *);
00035 
00036     /* Local variables */
00037     integer i__, j, k, ii, ki, is;
00038     doublereal ulp;
00039     logical allv;
00040     doublereal unfl, ovfl, smin;
00041     logical over;
00042     doublereal scale;
00043     extern logical lsame_(char *, char *);
00044     doublereal remax;
00045     logical leftv, bothv;
00046     extern /* Subroutine */ int zgemv_(char *, integer *, integer *, 
00047             doublecomplex *, doublecomplex *, integer *, doublecomplex *, 
00048             integer *, doublecomplex *, doublecomplex *, integer *);
00049     logical somev;
00050     extern /* Subroutine */ int zcopy_(integer *, doublecomplex *, integer *, 
00051             doublecomplex *, integer *), dlabad_(doublereal *, doublereal *);
00052     extern doublereal dlamch_(char *);
00053     extern /* Subroutine */ int xerbla_(char *, integer *), zdscal_(
00054             integer *, doublereal *, doublecomplex *, integer *);
00055     extern integer izamax_(integer *, doublecomplex *, integer *);
00056     logical rightv;
00057     extern doublereal dzasum_(integer *, doublecomplex *, integer *);
00058     doublereal smlnum;
00059     extern /* Subroutine */ int zlatrs_(char *, char *, char *, char *, 
00060             integer *, doublecomplex *, integer *, doublecomplex *, 
00061             doublereal *, doublereal *, integer *);
00062 
00063 
00064 /*  -- LAPACK routine (version 3.2) -- */
00065 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00066 /*     November 2006 */
00067 
00068 /*     .. Scalar Arguments .. */
00069 /*     .. */
00070 /*     .. Array Arguments .. */
00071 /*     .. */
00072 
00073 /*  Purpose */
00074 /*  ======= */
00075 
00076 /*  ZTREVC computes some or all of the right and/or left eigenvectors of */
00077 /*  a complex upper triangular matrix T. */
00078 /*  Matrices of this type are produced by the Schur factorization of */
00079 /*  a complex general matrix:  A = Q*T*Q**H, as computed by ZHSEQR. */
00080 
00081 /*  The right eigenvector x and the left eigenvector y of T corresponding */
00082 /*  to an eigenvalue w are defined by: */
00083 
00084 /*               T*x = w*x,     (y**H)*T = w*(y**H) */
00085 
00086 /*  where y**H denotes the conjugate transpose of the vector y. */
00087 /*  The eigenvalues are not input to this routine, but are read directly */
00088 /*  from the diagonal of T. */
00089 
00090 /*  This routine returns the matrices X and/or Y of right and left */
00091 /*  eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an */
00092 /*  input matrix.  If Q is the unitary factor that reduces a matrix A to */
00093 /*  Schur form T, then Q*X and Q*Y are the matrices of right and left */
00094 /*  eigenvectors of A. */
00095 
00096 /*  Arguments */
00097 /*  ========= */
00098 
00099 /*  SIDE    (input) CHARACTER*1 */
00100 /*          = 'R':  compute right eigenvectors only; */
00101 /*          = 'L':  compute left eigenvectors only; */
00102 /*          = 'B':  compute both right and left eigenvectors. */
00103 
00104 /*  HOWMNY  (input) CHARACTER*1 */
00105 /*          = 'A':  compute all right and/or left eigenvectors; */
00106 /*          = 'B':  compute all right and/or left eigenvectors, */
00107 /*                  backtransformed using the matrices supplied in */
00108 /*                  VR and/or VL; */
00109 /*          = 'S':  compute selected right and/or left eigenvectors, */
00110 /*                  as indicated by the logical array SELECT. */
00111 
00112 /*  SELECT  (input) LOGICAL array, dimension (N) */
00113 /*          If HOWMNY = 'S', SELECT specifies the eigenvectors to be */
00114 /*          computed. */
00115 /*          The eigenvector corresponding to the j-th eigenvalue is */
00116 /*          computed if SELECT(j) = .TRUE.. */
00117 /*          Not referenced if HOWMNY = 'A' or 'B'. */
00118 
00119 /*  N       (input) INTEGER */
00120 /*          The order of the matrix T. N >= 0. */
00121 
00122 /*  T       (input/output) COMPLEX*16 array, dimension (LDT,N) */
00123 /*          The upper triangular matrix T.  T is modified, but restored */
00124 /*          on exit. */
00125 
00126 /*  LDT     (input) INTEGER */
00127 /*          The leading dimension of the array T. LDT >= max(1,N). */
00128 
00129 /*  VL      (input/output) COMPLEX*16 array, dimension (LDVL,MM) */
00130 /*          On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must */
00131 /*          contain an N-by-N matrix Q (usually the unitary matrix Q of */
00132 /*          Schur vectors returned by ZHSEQR). */
00133 /*          On exit, if SIDE = 'L' or 'B', VL contains: */
00134 /*          if HOWMNY = 'A', the matrix Y of left eigenvectors of T; */
00135 /*          if HOWMNY = 'B', the matrix Q*Y; */
00136 /*          if HOWMNY = 'S', the left eigenvectors of T specified by */
00137 /*                           SELECT, stored consecutively in the columns */
00138 /*                           of VL, in the same order as their */
00139 /*                           eigenvalues. */
00140 /*          Not referenced if SIDE = 'R'. */
00141 
00142 /*  LDVL    (input) INTEGER */
00143 /*          The leading dimension of the array VL.  LDVL >= 1, and if */
00144 /*          SIDE = 'L' or 'B', LDVL >= N. */
00145 
00146 /*  VR      (input/output) COMPLEX*16 array, dimension (LDVR,MM) */
00147 /*          On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must */
00148 /*          contain an N-by-N matrix Q (usually the unitary matrix Q of */
00149 /*          Schur vectors returned by ZHSEQR). */
00150 /*          On exit, if SIDE = 'R' or 'B', VR contains: */
00151 /*          if HOWMNY = 'A', the matrix X of right eigenvectors of T; */
00152 /*          if HOWMNY = 'B', the matrix Q*X; */
00153 /*          if HOWMNY = 'S', the right eigenvectors of T specified by */
00154 /*                           SELECT, stored consecutively in the columns */
00155 /*                           of VR, in the same order as their */
00156 /*                           eigenvalues. */
00157 /*          Not referenced if SIDE = 'L'. */
00158 
00159 /*  LDVR    (input) INTEGER */
00160 /*          The leading dimension of the array VR.  LDVR >= 1, and if */
00161 /*          SIDE = 'R' or 'B'; LDVR >= N. */
00162 
00163 /*  MM      (input) INTEGER */
00164 /*          The number of columns in the arrays VL and/or VR. MM >= M. */
00165 
00166 /*  M       (output) INTEGER */
00167 /*          The number of columns in the arrays VL and/or VR actually */
00168 /*          used to store the eigenvectors.  If HOWMNY = 'A' or 'B', M */
00169 /*          is set to N.  Each selected eigenvector occupies one */
00170 /*          column. */
00171 
00172 /*  WORK    (workspace) COMPLEX*16 array, dimension (2*N) */
00173 
00174 /*  RWORK   (workspace) DOUBLE PRECISION array, dimension (N) */
00175 
00176 /*  INFO    (output) INTEGER */
00177 /*          = 0:  successful exit */
00178 /*          < 0:  if INFO = -i, the i-th argument had an illegal value */
00179 
00180 /*  Further Details */
00181 /*  =============== */
00182 
00183 /*  The algorithm used in this program is basically backward (forward) */
00184 /*  substitution, with scaling to make the the code robust against */
00185 /*  possible overflow. */
00186 
00187 /*  Each eigenvector is normalized so that the element of largest */
00188 /*  magnitude has magnitude 1; here the magnitude of a complex number */
00189 /*  (x,y) is taken to be |x| + |y|. */
00190 
00191 /*  ===================================================================== */
00192 
00193 /*     .. Parameters .. */
00194 /*     .. */
00195 /*     .. Local Scalars .. */
00196 /*     .. */
00197 /*     .. External Functions .. */
00198 /*     .. */
00199 /*     .. External Subroutines .. */
00200 /*     .. */
00201 /*     .. Intrinsic Functions .. */
00202 /*     .. */
00203 /*     .. Statement Functions .. */
00204 /*     .. */
00205 /*     .. Statement Function definitions .. */
00206 /*     .. */
00207 /*     .. Executable Statements .. */
00208 
00209 /*     Decode and test the input parameters */
00210 
00211     /* Parameter adjustments */
00212     --select;
00213     t_dim1 = *ldt;
00214     t_offset = 1 + t_dim1;
00215     t -= t_offset;
00216     vl_dim1 = *ldvl;
00217     vl_offset = 1 + vl_dim1;
00218     vl -= vl_offset;
00219     vr_dim1 = *ldvr;
00220     vr_offset = 1 + vr_dim1;
00221     vr -= vr_offset;
00222     --work;
00223     --rwork;
00224 
00225     /* Function Body */
00226     bothv = lsame_(side, "B");
00227     rightv = lsame_(side, "R") || bothv;
00228     leftv = lsame_(side, "L") || bothv;
00229 
00230     allv = lsame_(howmny, "A");
00231     over = lsame_(howmny, "B");
00232     somev = lsame_(howmny, "S");
00233 
00234 /*     Set M to the number of columns required to store the selected */
00235 /*     eigenvectors. */
00236 
00237     if (somev) {
00238         *m = 0;
00239         i__1 = *n;
00240         for (j = 1; j <= i__1; ++j) {
00241             if (select[j]) {
00242                 ++(*m);
00243             }
00244 /* L10: */
00245         }
00246     } else {
00247         *m = *n;
00248     }
00249 
00250     *info = 0;
00251     if (! rightv && ! leftv) {
00252         *info = -1;
00253     } else if (! allv && ! over && ! somev) {
00254         *info = -2;
00255     } else if (*n < 0) {
00256         *info = -4;
00257     } else if (*ldt < max(1,*n)) {
00258         *info = -6;
00259     } else if (*ldvl < 1 || leftv && *ldvl < *n) {
00260         *info = -8;
00261     } else if (*ldvr < 1 || rightv && *ldvr < *n) {
00262         *info = -10;
00263     } else if (*mm < *m) {
00264         *info = -11;
00265     }
00266     if (*info != 0) {
00267         i__1 = -(*info);
00268         xerbla_("ZTREVC", &i__1);
00269         return 0;
00270     }
00271 
00272 /*     Quick return if possible. */
00273 
00274     if (*n == 0) {
00275         return 0;
00276     }
00277 
00278 /*     Set the constants to control overflow. */
00279 
00280     unfl = dlamch_("Safe minimum");
00281     ovfl = 1. / unfl;
00282     dlabad_(&unfl, &ovfl);
00283     ulp = dlamch_("Precision");
00284     smlnum = unfl * (*n / ulp);
00285 
00286 /*     Store the diagonal elements of T in working array WORK. */
00287 
00288     i__1 = *n;
00289     for (i__ = 1; i__ <= i__1; ++i__) {
00290         i__2 = i__ + *n;
00291         i__3 = i__ + i__ * t_dim1;
00292         work[i__2].r = t[i__3].r, work[i__2].i = t[i__3].i;
00293 /* L20: */
00294     }
00295 
00296 /*     Compute 1-norm of each column of strictly upper triangular */
00297 /*     part of T to control overflow in triangular solver. */
00298 
00299     rwork[1] = 0.;
00300     i__1 = *n;
00301     for (j = 2; j <= i__1; ++j) {
00302         i__2 = j - 1;
00303         rwork[j] = dzasum_(&i__2, &t[j * t_dim1 + 1], &c__1);
00304 /* L30: */
00305     }
00306 
00307     if (rightv) {
00308 
00309 /*        Compute right eigenvectors. */
00310 
00311         is = *m;
00312         for (ki = *n; ki >= 1; --ki) {
00313 
00314             if (somev) {
00315                 if (! select[ki]) {
00316                     goto L80;
00317                 }
00318             }
00319 /* Computing MAX */
00320             i__1 = ki + ki * t_dim1;
00321             d__3 = ulp * ((d__1 = t[i__1].r, abs(d__1)) + (d__2 = d_imag(&t[
00322                     ki + ki * t_dim1]), abs(d__2)));
00323             smin = max(d__3,smlnum);
00324 
00325             work[1].r = 1., work[1].i = 0.;
00326 
00327 /*           Form right-hand side. */
00328 
00329             i__1 = ki - 1;
00330             for (k = 1; k <= i__1; ++k) {
00331                 i__2 = k;
00332                 i__3 = k + ki * t_dim1;
00333                 z__1.r = -t[i__3].r, z__1.i = -t[i__3].i;
00334                 work[i__2].r = z__1.r, work[i__2].i = z__1.i;
00335 /* L40: */
00336             }
00337 
00338 /*           Solve the triangular system: */
00339 /*              (T(1:KI-1,1:KI-1) - T(KI,KI))*X = SCALE*WORK. */
00340 
00341             i__1 = ki - 1;
00342             for (k = 1; k <= i__1; ++k) {
00343                 i__2 = k + k * t_dim1;
00344                 i__3 = k + k * t_dim1;
00345                 i__4 = ki + ki * t_dim1;
00346                 z__1.r = t[i__3].r - t[i__4].r, z__1.i = t[i__3].i - t[i__4]
00347                         .i;
00348                 t[i__2].r = z__1.r, t[i__2].i = z__1.i;
00349                 i__2 = k + k * t_dim1;
00350                 if ((d__1 = t[i__2].r, abs(d__1)) + (d__2 = d_imag(&t[k + k * 
00351                         t_dim1]), abs(d__2)) < smin) {
00352                     i__3 = k + k * t_dim1;
00353                     t[i__3].r = smin, t[i__3].i = 0.;
00354                 }
00355 /* L50: */
00356             }
00357 
00358             if (ki > 1) {
00359                 i__1 = ki - 1;
00360                 zlatrs_("Upper", "No transpose", "Non-unit", "Y", &i__1, &t[
00361                         t_offset], ldt, &work[1], &scale, &rwork[1], info);
00362                 i__1 = ki;
00363                 work[i__1].r = scale, work[i__1].i = 0.;
00364             }
00365 
00366 /*           Copy the vector x or Q*x to VR and normalize. */
00367 
00368             if (! over) {
00369                 zcopy_(&ki, &work[1], &c__1, &vr[is * vr_dim1 + 1], &c__1);
00370 
00371                 ii = izamax_(&ki, &vr[is * vr_dim1 + 1], &c__1);
00372                 i__1 = ii + is * vr_dim1;
00373                 remax = 1. / ((d__1 = vr[i__1].r, abs(d__1)) + (d__2 = d_imag(
00374                         &vr[ii + is * vr_dim1]), abs(d__2)));
00375                 zdscal_(&ki, &remax, &vr[is * vr_dim1 + 1], &c__1);
00376 
00377                 i__1 = *n;
00378                 for (k = ki + 1; k <= i__1; ++k) {
00379                     i__2 = k + is * vr_dim1;
00380                     vr[i__2].r = 0., vr[i__2].i = 0.;
00381 /* L60: */
00382                 }
00383             } else {
00384                 if (ki > 1) {
00385                     i__1 = ki - 1;
00386                     z__1.r = scale, z__1.i = 0.;
00387                     zgemv_("N", n, &i__1, &c_b2, &vr[vr_offset], ldvr, &work[
00388                             1], &c__1, &z__1, &vr[ki * vr_dim1 + 1], &c__1);
00389                 }
00390 
00391                 ii = izamax_(n, &vr[ki * vr_dim1 + 1], &c__1);
00392                 i__1 = ii + ki * vr_dim1;
00393                 remax = 1. / ((d__1 = vr[i__1].r, abs(d__1)) + (d__2 = d_imag(
00394                         &vr[ii + ki * vr_dim1]), abs(d__2)));
00395                 zdscal_(n, &remax, &vr[ki * vr_dim1 + 1], &c__1);
00396             }
00397 
00398 /*           Set back the original diagonal elements of T. */
00399 
00400             i__1 = ki - 1;
00401             for (k = 1; k <= i__1; ++k) {
00402                 i__2 = k + k * t_dim1;
00403                 i__3 = k + *n;
00404                 t[i__2].r = work[i__3].r, t[i__2].i = work[i__3].i;
00405 /* L70: */
00406             }
00407 
00408             --is;
00409 L80:
00410             ;
00411         }
00412     }
00413 
00414     if (leftv) {
00415 
00416 /*        Compute left eigenvectors. */
00417 
00418         is = 1;
00419         i__1 = *n;
00420         for (ki = 1; ki <= i__1; ++ki) {
00421 
00422             if (somev) {
00423                 if (! select[ki]) {
00424                     goto L130;
00425                 }
00426             }
00427 /* Computing MAX */
00428             i__2 = ki + ki * t_dim1;
00429             d__3 = ulp * ((d__1 = t[i__2].r, abs(d__1)) + (d__2 = d_imag(&t[
00430                     ki + ki * t_dim1]), abs(d__2)));
00431             smin = max(d__3,smlnum);
00432 
00433             i__2 = *n;
00434             work[i__2].r = 1., work[i__2].i = 0.;
00435 
00436 /*           Form right-hand side. */
00437 
00438             i__2 = *n;
00439             for (k = ki + 1; k <= i__2; ++k) {
00440                 i__3 = k;
00441                 d_cnjg(&z__2, &t[ki + k * t_dim1]);
00442                 z__1.r = -z__2.r, z__1.i = -z__2.i;
00443                 work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00444 /* L90: */
00445             }
00446 
00447 /*           Solve the triangular system: */
00448 /*              (T(KI+1:N,KI+1:N) - T(KI,KI))'*X = SCALE*WORK. */
00449 
00450             i__2 = *n;
00451             for (k = ki + 1; k <= i__2; ++k) {
00452                 i__3 = k + k * t_dim1;
00453                 i__4 = k + k * t_dim1;
00454                 i__5 = ki + ki * t_dim1;
00455                 z__1.r = t[i__4].r - t[i__5].r, z__1.i = t[i__4].i - t[i__5]
00456                         .i;
00457                 t[i__3].r = z__1.r, t[i__3].i = z__1.i;
00458                 i__3 = k + k * t_dim1;
00459                 if ((d__1 = t[i__3].r, abs(d__1)) + (d__2 = d_imag(&t[k + k * 
00460                         t_dim1]), abs(d__2)) < smin) {
00461                     i__4 = k + k * t_dim1;
00462                     t[i__4].r = smin, t[i__4].i = 0.;
00463                 }
00464 /* L100: */
00465             }
00466 
00467             if (ki < *n) {
00468                 i__2 = *n - ki;
00469                 zlatrs_("Upper", "Conjugate transpose", "Non-unit", "Y", &
00470                         i__2, &t[ki + 1 + (ki + 1) * t_dim1], ldt, &work[ki + 
00471                         1], &scale, &rwork[1], info);
00472                 i__2 = ki;
00473                 work[i__2].r = scale, work[i__2].i = 0.;
00474             }
00475 
00476 /*           Copy the vector x or Q*x to VL and normalize. */
00477 
00478             if (! over) {
00479                 i__2 = *n - ki + 1;
00480                 zcopy_(&i__2, &work[ki], &c__1, &vl[ki + is * vl_dim1], &c__1)
00481                         ;
00482 
00483                 i__2 = *n - ki + 1;
00484                 ii = izamax_(&i__2, &vl[ki + is * vl_dim1], &c__1) + ki - 1;
00485                 i__2 = ii + is * vl_dim1;
00486                 remax = 1. / ((d__1 = vl[i__2].r, abs(d__1)) + (d__2 = d_imag(
00487                         &vl[ii + is * vl_dim1]), abs(d__2)));
00488                 i__2 = *n - ki + 1;
00489                 zdscal_(&i__2, &remax, &vl[ki + is * vl_dim1], &c__1);
00490 
00491                 i__2 = ki - 1;
00492                 for (k = 1; k <= i__2; ++k) {
00493                     i__3 = k + is * vl_dim1;
00494                     vl[i__3].r = 0., vl[i__3].i = 0.;
00495 /* L110: */
00496                 }
00497             } else {
00498                 if (ki < *n) {
00499                     i__2 = *n - ki;
00500                     z__1.r = scale, z__1.i = 0.;
00501                     zgemv_("N", n, &i__2, &c_b2, &vl[(ki + 1) * vl_dim1 + 1], 
00502                             ldvl, &work[ki + 1], &c__1, &z__1, &vl[ki * 
00503                             vl_dim1 + 1], &c__1);
00504                 }
00505 
00506                 ii = izamax_(n, &vl[ki * vl_dim1 + 1], &c__1);
00507                 i__2 = ii + ki * vl_dim1;
00508                 remax = 1. / ((d__1 = vl[i__2].r, abs(d__1)) + (d__2 = d_imag(
00509                         &vl[ii + ki * vl_dim1]), abs(d__2)));
00510                 zdscal_(n, &remax, &vl[ki * vl_dim1 + 1], &c__1);
00511             }
00512 
00513 /*           Set back the original diagonal elements of T. */
00514 
00515             i__2 = *n;
00516             for (k = ki + 1; k <= i__2; ++k) {
00517                 i__3 = k + k * t_dim1;
00518                 i__4 = k + *n;
00519                 t[i__3].r = work[i__4].r, t[i__3].i = work[i__4].i;
00520 /* L120: */
00521             }
00522 
00523             ++is;
00524 L130:
00525             ;
00526         }
00527     }
00528 
00529     return 0;
00530 
00531 /*     End of ZTREVC */
00532 
00533 } /* ztrevc_ */


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