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


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:55:45