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_ */