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