shsein.c
Go to the documentation of this file.
00001 /* shsein.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 logical c_false = FALSE_;
00019 static logical c_true = TRUE_;
00020 
00021 /* Subroutine */ int shsein_(char *side, char *eigsrc, char *initv, logical *
00022         select, integer *n, real *h__, integer *ldh, real *wr, real *wi, real 
00023         *vl, integer *ldvl, real *vr, integer *ldvr, integer *mm, integer *m, 
00024         real *work, integer *ifaill, integer *ifailr, integer *info)
00025 {
00026     /* System generated locals */
00027     integer h_dim1, h_offset, vl_dim1, vl_offset, vr_dim1, vr_offset, i__1, 
00028             i__2;
00029     real r__1, r__2;
00030 
00031     /* Local variables */
00032     integer i__, k, kl, kr, kln, ksi;
00033     real wki;
00034     integer ksr;
00035     real ulp, wkr, eps3;
00036     logical pair;
00037     real unfl;
00038     extern logical lsame_(char *, char *);
00039     integer iinfo;
00040     logical leftv, bothv;
00041     real hnorm;
00042     extern doublereal slamch_(char *);
00043     extern /* Subroutine */ int slaein_(logical *, logical *, integer *, real 
00044             *, integer *, real *, real *, real *, real *, real *, integer *, 
00045             real *, real *, real *, real *, integer *), xerbla_(char *, 
00046             integer *);
00047     real bignum;
00048     extern doublereal slanhs_(char *, integer *, real *, integer *, real *);
00049     logical noinit;
00050     integer ldwork;
00051     logical rightv, fromqr;
00052     real smlnum;
00053 
00054 
00055 /*  -- LAPACK routine (version 3.2) -- */
00056 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00057 /*     November 2006 */
00058 
00059 /*     .. Scalar Arguments .. */
00060 /*     .. */
00061 /*     .. Array Arguments .. */
00062 /*     .. */
00063 
00064 /*  Purpose */
00065 /*  ======= */
00066 
00067 /*  SHSEIN uses inverse iteration to find specified right and/or left */
00068 /*  eigenvectors of a real upper Hessenberg matrix H. */
00069 
00070 /*  The right eigenvector x and the left eigenvector y of the matrix H */
00071 /*  corresponding to an eigenvalue w are defined by: */
00072 
00073 /*               H * x = w * x,     y**h * H = w * y**h */
00074 
00075 /*  where y**h denotes the conjugate transpose of the vector y. */
00076 
00077 /*  Arguments */
00078 /*  ========= */
00079 
00080 /*  SIDE    (input) CHARACTER*1 */
00081 /*          = 'R': compute right eigenvectors only; */
00082 /*          = 'L': compute left eigenvectors only; */
00083 /*          = 'B': compute both right and left eigenvectors. */
00084 
00085 /*  EIGSRC  (input) CHARACTER*1 */
00086 /*          Specifies the source of eigenvalues supplied in (WR,WI): */
00087 /*          = 'Q': the eigenvalues were found using SHSEQR; thus, if */
00088 /*                 H has zero subdiagonal elements, and so is */
00089 /*                 block-triangular, then the j-th eigenvalue can be */
00090 /*                 assumed to be an eigenvalue of the block containing */
00091 /*                 the j-th row/column.  This property allows SHSEIN to */
00092 /*                 perform inverse iteration on just one diagonal block. */
00093 /*          = 'N': no assumptions are made on the correspondence */
00094 /*                 between eigenvalues and diagonal blocks.  In this */
00095 /*                 case, SHSEIN must always perform inverse iteration */
00096 /*                 using the whole matrix H. */
00097 
00098 /*  INITV   (input) CHARACTER*1 */
00099 /*          = 'N': no initial vectors are supplied; */
00100 /*          = 'U': user-supplied initial vectors are stored in the arrays */
00101 /*                 VL and/or VR. */
00102 
00103 /*  SELECT  (input/output) LOGICAL array, dimension (N) */
00104 /*          Specifies the eigenvectors to be computed. To select the */
00105 /*          real eigenvector corresponding to a real eigenvalue WR(j), */
00106 /*          SELECT(j) must be set to .TRUE.. To select the complex */
00107 /*          eigenvector corresponding to a complex eigenvalue */
00108 /*          (WR(j),WI(j)), with complex conjugate (WR(j+1),WI(j+1)), */
00109 /*          either SELECT(j) or SELECT(j+1) or both must be set to */
00110 /*          .TRUE.; then on exit SELECT(j) is .TRUE. and SELECT(j+1) is */
00111 /*          .FALSE.. */
00112 
00113 /*  N       (input) INTEGER */
00114 /*          The order of the matrix H.  N >= 0. */
00115 
00116 /*  H       (input) REAL array, dimension (LDH,N) */
00117 /*          The upper Hessenberg matrix H. */
00118 
00119 /*  LDH     (input) INTEGER */
00120 /*          The leading dimension of the array H.  LDH >= max(1,N). */
00121 
00122 /*  WR      (input/output) REAL array, dimension (N) */
00123 /*  WI      (input) REAL array, dimension (N) */
00124 /*          On entry, the real and imaginary parts of the eigenvalues of */
00125 /*          H; a complex conjugate pair of eigenvalues must be stored in */
00126 /*          consecutive elements of WR and WI. */
00127 /*          On exit, WR may have been altered since close eigenvalues */
00128 /*          are perturbed slightly in searching for independent */
00129 /*          eigenvectors. */
00130 
00131 /*  VL      (input/output) REAL array, dimension (LDVL,MM) */
00132 /*          On entry, if INITV = 'U' and SIDE = 'L' or 'B', VL must */
00133 /*          contain starting vectors for the inverse iteration for the */
00134 /*          left eigenvectors; the starting vector for each eigenvector */
00135 /*          must be in the same column(s) in which the eigenvector will */
00136 /*          be stored. */
00137 /*          On exit, if SIDE = 'L' or 'B', the left eigenvectors */
00138 /*          specified by SELECT will be stored consecutively in the */
00139 /*          columns of VL, in the same order as their eigenvalues. A */
00140 /*          complex eigenvector corresponding to a complex eigenvalue is */
00141 /*          stored in two consecutive columns, the first holding the real */
00142 /*          part and the second the imaginary part. */
00143 /*          If SIDE = 'R', VL is not referenced. */
00144 
00145 /*  LDVL    (input) INTEGER */
00146 /*          The leading dimension of the array VL. */
00147 /*          LDVL >= max(1,N) if SIDE = 'L' or 'B'; LDVL >= 1 otherwise. */
00148 
00149 /*  VR      (input/output) REAL array, dimension (LDVR,MM) */
00150 /*          On entry, if INITV = 'U' and SIDE = 'R' or 'B', VR must */
00151 /*          contain starting vectors for the inverse iteration for the */
00152 /*          right eigenvectors; the starting vector for each eigenvector */
00153 /*          must be in the same column(s) in which the eigenvector will */
00154 /*          be stored. */
00155 /*          On exit, if SIDE = 'R' or 'B', the right eigenvectors */
00156 /*          specified by SELECT will be stored consecutively in the */
00157 /*          columns of VR, in the same order as their eigenvalues. A */
00158 /*          complex eigenvector corresponding to a complex eigenvalue is */
00159 /*          stored in two consecutive columns, the first holding the real */
00160 /*          part and the second the imaginary part. */
00161 /*          If SIDE = 'L', VR is not referenced. */
00162 
00163 /*  LDVR    (input) INTEGER */
00164 /*          The leading dimension of the array VR. */
00165 /*          LDVR >= max(1,N) if SIDE = 'R' or 'B'; LDVR >= 1 otherwise. */
00166 
00167 /*  MM      (input) INTEGER */
00168 /*          The number of columns in the arrays VL and/or VR. MM >= M. */
00169 
00170 /*  M       (output) INTEGER */
00171 /*          The number of columns in the arrays VL and/or VR required to */
00172 /*          store the eigenvectors; each selected real eigenvector */
00173 /*          occupies one column and each selected complex eigenvector */
00174 /*          occupies two columns. */
00175 
00176 /*  WORK    (workspace) REAL array, dimension ((N+2)*N) */
00177 
00178 /*  IFAILL  (output) INTEGER array, dimension (MM) */
00179 /*          If SIDE = 'L' or 'B', IFAILL(i) = j > 0 if the left */
00180 /*          eigenvector in the i-th column of VL (corresponding to the */
00181 /*          eigenvalue w(j)) failed to converge; IFAILL(i) = 0 if the */
00182 /*          eigenvector converged satisfactorily. If the i-th and (i+1)th */
00183 /*          columns of VL hold a complex eigenvector, then IFAILL(i) and */
00184 /*          IFAILL(i+1) are set to the same value. */
00185 /*          If SIDE = 'R', IFAILL is not referenced. */
00186 
00187 /*  IFAILR  (output) INTEGER array, dimension (MM) */
00188 /*          If SIDE = 'R' or 'B', IFAILR(i) = j > 0 if the right */
00189 /*          eigenvector in the i-th column of VR (corresponding to the */
00190 /*          eigenvalue w(j)) failed to converge; IFAILR(i) = 0 if the */
00191 /*          eigenvector converged satisfactorily. If the i-th and (i+1)th */
00192 /*          columns of VR hold a complex eigenvector, then IFAILR(i) and */
00193 /*          IFAILR(i+1) are set to the same value. */
00194 /*          If SIDE = 'L', IFAILR is not referenced. */
00195 
00196 /*  INFO    (output) INTEGER */
00197 /*          = 0:  successful exit */
00198 /*          < 0:  if INFO = -i, the i-th argument had an illegal value */
00199 /*          > 0:  if INFO = i, i is the number of eigenvectors which */
00200 /*                failed to converge; see IFAILL and IFAILR for further */
00201 /*                details. */
00202 
00203 /*  Further Details */
00204 /*  =============== */
00205 
00206 /*  Each eigenvector is normalized so that the element of largest */
00207 /*  magnitude has magnitude 1; here the magnitude of a complex number */
00208 /*  (x,y) is taken to be |x|+|y|. */
00209 
00210 /*  ===================================================================== */
00211 
00212 /*     .. Parameters .. */
00213 /*     .. */
00214 /*     .. Local Scalars .. */
00215 /*     .. */
00216 /*     .. External Functions .. */
00217 /*     .. */
00218 /*     .. External Subroutines .. */
00219 /*     .. */
00220 /*     .. Intrinsic Functions .. */
00221 /*     .. */
00222 /*     .. Executable Statements .. */
00223 
00224 /*     Decode and test the input parameters. */
00225 
00226     /* Parameter adjustments */
00227     --select;
00228     h_dim1 = *ldh;
00229     h_offset = 1 + h_dim1;
00230     h__ -= h_offset;
00231     --wr;
00232     --wi;
00233     vl_dim1 = *ldvl;
00234     vl_offset = 1 + vl_dim1;
00235     vl -= vl_offset;
00236     vr_dim1 = *ldvr;
00237     vr_offset = 1 + vr_dim1;
00238     vr -= vr_offset;
00239     --work;
00240     --ifaill;
00241     --ifailr;
00242 
00243     /* Function Body */
00244     bothv = lsame_(side, "B");
00245     rightv = lsame_(side, "R") || bothv;
00246     leftv = lsame_(side, "L") || bothv;
00247 
00248     fromqr = lsame_(eigsrc, "Q");
00249 
00250     noinit = lsame_(initv, "N");
00251 
00252 /*     Set M to the number of columns required to store the selected */
00253 /*     eigenvectors, and standardize the array SELECT. */
00254 
00255     *m = 0;
00256     pair = FALSE_;
00257     i__1 = *n;
00258     for (k = 1; k <= i__1; ++k) {
00259         if (pair) {
00260             pair = FALSE_;
00261             select[k] = FALSE_;
00262         } else {
00263             if (wi[k] == 0.f) {
00264                 if (select[k]) {
00265                     ++(*m);
00266                 }
00267             } else {
00268                 pair = TRUE_;
00269                 if (select[k] || select[k + 1]) {
00270                     select[k] = TRUE_;
00271                     *m += 2;
00272                 }
00273             }
00274         }
00275 /* L10: */
00276     }
00277 
00278     *info = 0;
00279     if (! rightv && ! leftv) {
00280         *info = -1;
00281     } else if (! fromqr && ! lsame_(eigsrc, "N")) {
00282         *info = -2;
00283     } else if (! noinit && ! lsame_(initv, "U")) {
00284         *info = -3;
00285     } else if (*n < 0) {
00286         *info = -5;
00287     } else if (*ldh < max(1,*n)) {
00288         *info = -7;
00289     } else if (*ldvl < 1 || leftv && *ldvl < *n) {
00290         *info = -11;
00291     } else if (*ldvr < 1 || rightv && *ldvr < *n) {
00292         *info = -13;
00293     } else if (*mm < *m) {
00294         *info = -14;
00295     }
00296     if (*info != 0) {
00297         i__1 = -(*info);
00298         xerbla_("SHSEIN", &i__1);
00299         return 0;
00300     }
00301 
00302 /*     Quick return if possible. */
00303 
00304     if (*n == 0) {
00305         return 0;
00306     }
00307 
00308 /*     Set machine-dependent constants. */
00309 
00310     unfl = slamch_("Safe minimum");
00311     ulp = slamch_("Precision");
00312     smlnum = unfl * (*n / ulp);
00313     bignum = (1.f - ulp) / smlnum;
00314 
00315     ldwork = *n + 1;
00316 
00317     kl = 1;
00318     kln = 0;
00319     if (fromqr) {
00320         kr = 0;
00321     } else {
00322         kr = *n;
00323     }
00324     ksr = 1;
00325 
00326     i__1 = *n;
00327     for (k = 1; k <= i__1; ++k) {
00328         if (select[k]) {
00329 
00330 /*           Compute eigenvector(s) corresponding to W(K). */
00331 
00332             if (fromqr) {
00333 
00334 /*              If affiliation of eigenvalues is known, check whether */
00335 /*              the matrix splits. */
00336 
00337 /*              Determine KL and KR such that 1 <= KL <= K <= KR <= N */
00338 /*              and H(KL,KL-1) and H(KR+1,KR) are zero (or KL = 1 or */
00339 /*              KR = N). */
00340 
00341 /*              Then inverse iteration can be performed with the */
00342 /*              submatrix H(KL:N,KL:N) for a left eigenvector, and with */
00343 /*              the submatrix H(1:KR,1:KR) for a right eigenvector. */
00344 
00345                 i__2 = kl + 1;
00346                 for (i__ = k; i__ >= i__2; --i__) {
00347                     if (h__[i__ + (i__ - 1) * h_dim1] == 0.f) {
00348                         goto L30;
00349                     }
00350 /* L20: */
00351                 }
00352 L30:
00353                 kl = i__;
00354                 if (k > kr) {
00355                     i__2 = *n - 1;
00356                     for (i__ = k; i__ <= i__2; ++i__) {
00357                         if (h__[i__ + 1 + i__ * h_dim1] == 0.f) {
00358                             goto L50;
00359                         }
00360 /* L40: */
00361                     }
00362 L50:
00363                     kr = i__;
00364                 }
00365             }
00366 
00367             if (kl != kln) {
00368                 kln = kl;
00369 
00370 /*              Compute infinity-norm of submatrix H(KL:KR,KL:KR) if it */
00371 /*              has not ben computed before. */
00372 
00373                 i__2 = kr - kl + 1;
00374                 hnorm = slanhs_("I", &i__2, &h__[kl + kl * h_dim1], ldh, &
00375                         work[1]);
00376                 if (hnorm > 0.f) {
00377                     eps3 = hnorm * ulp;
00378                 } else {
00379                     eps3 = smlnum;
00380                 }
00381             }
00382 
00383 /*           Perturb eigenvalue if it is close to any previous */
00384 /*           selected eigenvalues affiliated to the submatrix */
00385 /*           H(KL:KR,KL:KR). Close roots are modified by EPS3. */
00386 
00387             wkr = wr[k];
00388             wki = wi[k];
00389 L60:
00390             i__2 = kl;
00391             for (i__ = k - 1; i__ >= i__2; --i__) {
00392                 if (select[i__] && (r__1 = wr[i__] - wkr, dabs(r__1)) + (r__2 
00393                         = wi[i__] - wki, dabs(r__2)) < eps3) {
00394                     wkr += eps3;
00395                     goto L60;
00396                 }
00397 /* L70: */
00398             }
00399             wr[k] = wkr;
00400 
00401             pair = wki != 0.f;
00402             if (pair) {
00403                 ksi = ksr + 1;
00404             } else {
00405                 ksi = ksr;
00406             }
00407             if (leftv) {
00408 
00409 /*              Compute left eigenvector. */
00410 
00411                 i__2 = *n - kl + 1;
00412                 slaein_(&c_false, &noinit, &i__2, &h__[kl + kl * h_dim1], ldh, 
00413                          &wkr, &wki, &vl[kl + ksr * vl_dim1], &vl[kl + ksi * 
00414                         vl_dim1], &work[1], &ldwork, &work[*n * *n + *n + 1], 
00415                         &eps3, &smlnum, &bignum, &iinfo);
00416                 if (iinfo > 0) {
00417                     if (pair) {
00418                         *info += 2;
00419                     } else {
00420                         ++(*info);
00421                     }
00422                     ifaill[ksr] = k;
00423                     ifaill[ksi] = k;
00424                 } else {
00425                     ifaill[ksr] = 0;
00426                     ifaill[ksi] = 0;
00427                 }
00428                 i__2 = kl - 1;
00429                 for (i__ = 1; i__ <= i__2; ++i__) {
00430                     vl[i__ + ksr * vl_dim1] = 0.f;
00431 /* L80: */
00432                 }
00433                 if (pair) {
00434                     i__2 = kl - 1;
00435                     for (i__ = 1; i__ <= i__2; ++i__) {
00436                         vl[i__ + ksi * vl_dim1] = 0.f;
00437 /* L90: */
00438                     }
00439                 }
00440             }
00441             if (rightv) {
00442 
00443 /*              Compute right eigenvector. */
00444 
00445                 slaein_(&c_true, &noinit, &kr, &h__[h_offset], ldh, &wkr, &
00446                         wki, &vr[ksr * vr_dim1 + 1], &vr[ksi * vr_dim1 + 1], &
00447                         work[1], &ldwork, &work[*n * *n + *n + 1], &eps3, &
00448                         smlnum, &bignum, &iinfo);
00449                 if (iinfo > 0) {
00450                     if (pair) {
00451                         *info += 2;
00452                     } else {
00453                         ++(*info);
00454                     }
00455                     ifailr[ksr] = k;
00456                     ifailr[ksi] = k;
00457                 } else {
00458                     ifailr[ksr] = 0;
00459                     ifailr[ksi] = 0;
00460                 }
00461                 i__2 = *n;
00462                 for (i__ = kr + 1; i__ <= i__2; ++i__) {
00463                     vr[i__ + ksr * vr_dim1] = 0.f;
00464 /* L100: */
00465                 }
00466                 if (pair) {
00467                     i__2 = *n;
00468                     for (i__ = kr + 1; i__ <= i__2; ++i__) {
00469                         vr[i__ + ksi * vr_dim1] = 0.f;
00470 /* L110: */
00471                     }
00472                 }
00473             }
00474 
00475             if (pair) {
00476                 ksr += 2;
00477             } else {
00478                 ++ksr;
00479             }
00480         }
00481 /* L120: */
00482     }
00483 
00484     return 0;
00485 
00486 /*     End of SHSEIN */
00487 
00488 } /* shsein_ */


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