Doxygen Source Code Documentation
eis_comqr.c File Reference
#include "f2c.h"
Go to the source code of this file.
Functions | |
int | comqr_ (integer *nm, integer *n, integer *low, integer *igh, doublereal *hr, doublereal *hi, doublereal *wr, doublereal *wi, integer *ierr) |
Function Documentation
|
Definition at line 8 of file eis_comqr.c. References abs, cdiv_(), csroot_(), l, min, and pythag_(). Referenced by cg_().
00011 { 00012 /* System generated locals */ 00013 integer hr_dim1, hr_offset, hi_dim1, hi_offset, i__1, i__2; 00014 doublereal d__1, d__2, d__3, d__4; 00015 00016 /* Local variables */ 00017 extern /* Subroutine */ int cdiv_(doublereal *, doublereal *, doublereal * 00018 , doublereal *, doublereal *, doublereal *); 00019 static doublereal norm; 00020 static integer i__, j, l, en, ll; 00021 static doublereal si, ti, xi, yi, sr, tr, xr, yr; 00022 extern doublereal pythag_(doublereal *, doublereal *); 00023 extern /* Subroutine */ int csroot_(doublereal *, doublereal *, 00024 doublereal *, doublereal *); 00025 static integer lp1, itn, its; 00026 static doublereal zzi, zzr; 00027 static integer enm1; 00028 static doublereal tst1, tst2; 00029 00030 00031 00032 /* THIS SUBROUTINE IS A TRANSLATION OF A UNITARY ANALOGUE OF THE */ 00033 /* ALGOL PROCEDURE COMLR, NUM. MATH. 12, 369-376(1968) BY MARTIN */ 00034 /* AND WILKINSON. */ 00035 /* HANDBOOK FOR AUTO. COMP., VOL.II-LINEAR ALGEBRA, 396-403(1971). */ 00036 /* THE UNITARY ANALOGUE SUBSTITUTES THE QR ALGORITHM OF FRANCIS */ 00037 /* (COMP. JOUR. 4, 332-345(1962)) FOR THE LR ALGORITHM. */ 00038 00039 /* THIS SUBROUTINE FINDS THE EIGENVALUES OF A COMPLEX */ 00040 /* UPPER HESSENBERG MATRIX BY THE QR METHOD. */ 00041 00042 /* ON INPUT */ 00043 00044 /* NM MUST BE SET TO THE ROW DIMENSION OF TWO-DIMENSIONAL */ 00045 /* ARRAY PARAMETERS AS DECLARED IN THE CALLING PROGRAM */ 00046 /* DIMENSION STATEMENT. */ 00047 00048 /* N IS THE ORDER OF THE MATRIX. */ 00049 00050 /* LOW AND IGH ARE INTEGERS DETERMINED BY THE BALANCING */ 00051 /* SUBROUTINE CBAL. IF CBAL HAS NOT BEEN USED, */ 00052 /* SET LOW=1, IGH=N. */ 00053 00054 /* HR AND HI CONTAIN THE REAL AND IMAGINARY PARTS, */ 00055 /* RESPECTIVELY, OF THE COMPLEX UPPER HESSENBERG MATRIX. */ 00056 /* THEIR LOWER TRIANGLES BELOW THE SUBDIAGONAL CONTAIN */ 00057 /* INFORMATION ABOUT THE UNITARY TRANSFORMATIONS USED IN */ 00058 /* THE REDUCTION BY CORTH, IF PERFORMED. */ 00059 00060 /* ON OUTPUT */ 00061 00062 /* THE UPPER HESSENBERG PORTIONS OF HR AND HI HAVE BEEN */ 00063 /* DESTROYED. THEREFORE, THEY MUST BE SAVED BEFORE */ 00064 /* CALLING COMQR IF SUBSEQUENT CALCULATION OF */ 00065 /* EIGENVECTORS IS TO BE PERFORMED. */ 00066 00067 /* WR AND WI CONTAIN THE REAL AND IMAGINARY PARTS, */ 00068 /* RESPECTIVELY, OF THE EIGENVALUES. IF AN ERROR */ 00069 /* EXIT IS MADE, THE EIGENVALUES SHOULD BE CORRECT */ 00070 /* FOR INDICES IERR+1,...,N. */ 00071 00072 /* IERR IS SET TO */ 00073 /* ZERO FOR NORMAL RETURN, */ 00074 /* J IF THE LIMIT OF 30*N ITERATIONS IS EXHAUSTED */ 00075 /* WHILE THE J-TH EIGENVALUE IS BEING SOUGHT. */ 00076 00077 /* CALLS CDIV FOR COMPLEX DIVISION. */ 00078 /* CALLS CSROOT FOR COMPLEX SQUARE ROOT. */ 00079 /* CALLS PYTHAG FOR DSQRT(A*A + B*B) . */ 00080 00081 /* QUESTIONS AND COMMENTS SHOULD BE DIRECTED TO BURTON S. GARBOW, */ 00082 /* MATHEMATICS AND COMPUTER SCIENCE DIV, ARGONNE NATIONAL LABORATORY 00083 */ 00084 00085 /* THIS VERSION DATED AUGUST 1983. */ 00086 00087 /* ------------------------------------------------------------------ 00088 */ 00089 00090 /* Parameter adjustments */ 00091 --wi; 00092 --wr; 00093 hi_dim1 = *nm; 00094 hi_offset = hi_dim1 + 1; 00095 hi -= hi_offset; 00096 hr_dim1 = *nm; 00097 hr_offset = hr_dim1 + 1; 00098 hr -= hr_offset; 00099 00100 /* Function Body */ 00101 *ierr = 0; 00102 if (*low == *igh) { 00103 goto L180; 00104 } 00105 /* .......... CREATE REAL SUBDIAGONAL ELEMENTS .......... */ 00106 l = *low + 1; 00107 00108 i__1 = *igh; 00109 for (i__ = l; i__ <= i__1; ++i__) { 00110 /* Computing MIN */ 00111 i__2 = i__ + 1; 00112 ll = min(i__2,*igh); 00113 if (hi[i__ + (i__ - 1) * hi_dim1] == 0.) { 00114 goto L170; 00115 } 00116 norm = pythag_(&hr[i__ + (i__ - 1) * hr_dim1], &hi[i__ + (i__ - 1) * 00117 hi_dim1]); 00118 yr = hr[i__ + (i__ - 1) * hr_dim1] / norm; 00119 yi = hi[i__ + (i__ - 1) * hi_dim1] / norm; 00120 hr[i__ + (i__ - 1) * hr_dim1] = norm; 00121 hi[i__ + (i__ - 1) * hi_dim1] = 0.; 00122 00123 i__2 = *igh; 00124 for (j = i__; j <= i__2; ++j) { 00125 si = yr * hi[i__ + j * hi_dim1] - yi * hr[i__ + j * hr_dim1]; 00126 hr[i__ + j * hr_dim1] = yr * hr[i__ + j * hr_dim1] + yi * hi[i__ 00127 + j * hi_dim1]; 00128 hi[i__ + j * hi_dim1] = si; 00129 /* L155: */ 00130 } 00131 00132 i__2 = ll; 00133 for (j = *low; j <= i__2; ++j) { 00134 si = yr * hi[j + i__ * hi_dim1] + yi * hr[j + i__ * hr_dim1]; 00135 hr[j + i__ * hr_dim1] = yr * hr[j + i__ * hr_dim1] - yi * hi[j + 00136 i__ * hi_dim1]; 00137 hi[j + i__ * hi_dim1] = si; 00138 /* L160: */ 00139 } 00140 00141 L170: 00142 ; 00143 } 00144 /* .......... STORE ROOTS ISOLATED BY CBAL .......... */ 00145 L180: 00146 i__1 = *n; 00147 for (i__ = 1; i__ <= i__1; ++i__) { 00148 if (i__ >= *low && i__ <= *igh) { 00149 goto L200; 00150 } 00151 wr[i__] = hr[i__ + i__ * hr_dim1]; 00152 wi[i__] = hi[i__ + i__ * hi_dim1]; 00153 L200: 00154 ; 00155 } 00156 00157 en = *igh; 00158 tr = 0.; 00159 ti = 0.; 00160 itn = *n * 30; 00161 /* .......... SEARCH FOR NEXT EIGENVALUE .......... */ 00162 L220: 00163 if (en < *low) { 00164 goto L1001; 00165 } 00166 its = 0; 00167 enm1 = en - 1; 00168 /* .......... LOOK FOR SINGLE SMALL SUB-DIAGONAL ELEMENT */ 00169 /* FOR L=EN STEP -1 UNTIL LOW D0 -- .......... */ 00170 L240: 00171 i__1 = en; 00172 for (ll = *low; ll <= i__1; ++ll) { 00173 l = en + *low - ll; 00174 if (l == *low) { 00175 goto L300; 00176 } 00177 tst1 = (d__1 = hr[l - 1 + (l - 1) * hr_dim1], abs(d__1)) + (d__2 = hi[ 00178 l - 1 + (l - 1) * hi_dim1], abs(d__2)) + (d__3 = hr[l + l * 00179 hr_dim1], abs(d__3)) + (d__4 = hi[l + l * hi_dim1], abs(d__4)) 00180 ; 00181 tst2 = tst1 + (d__1 = hr[l + (l - 1) * hr_dim1], abs(d__1)); 00182 if (tst2 == tst1) { 00183 goto L300; 00184 } 00185 /* L260: */ 00186 } 00187 /* .......... FORM SHIFT .......... */ 00188 L300: 00189 if (l == en) { 00190 goto L660; 00191 } 00192 if (itn == 0) { 00193 goto L1000; 00194 } 00195 if (its == 10 || its == 20) { 00196 goto L320; 00197 } 00198 sr = hr[en + en * hr_dim1]; 00199 si = hi[en + en * hi_dim1]; 00200 xr = hr[enm1 + en * hr_dim1] * hr[en + enm1 * hr_dim1]; 00201 xi = hi[enm1 + en * hi_dim1] * hr[en + enm1 * hr_dim1]; 00202 if (xr == 0. && xi == 0.) { 00203 goto L340; 00204 } 00205 yr = (hr[enm1 + enm1 * hr_dim1] - sr) / 2.; 00206 yi = (hi[enm1 + enm1 * hi_dim1] - si) / 2.; 00207 /* Computing 2nd power */ 00208 d__2 = yr; 00209 /* Computing 2nd power */ 00210 d__3 = yi; 00211 d__1 = d__2 * d__2 - d__3 * d__3 + xr; 00212 d__4 = yr * 2. * yi + xi; 00213 csroot_(&d__1, &d__4, &zzr, &zzi); 00214 if (yr * zzr + yi * zzi >= 0.) { 00215 goto L310; 00216 } 00217 zzr = -zzr; 00218 zzi = -zzi; 00219 L310: 00220 d__1 = yr + zzr; 00221 d__2 = yi + zzi; 00222 cdiv_(&xr, &xi, &d__1, &d__2, &xr, &xi); 00223 sr -= xr; 00224 si -= xi; 00225 goto L340; 00226 /* .......... FORM EXCEPTIONAL SHIFT .......... */ 00227 L320: 00228 sr = (d__1 = hr[en + enm1 * hr_dim1], abs(d__1)) + (d__2 = hr[enm1 + (en 00229 - 2) * hr_dim1], abs(d__2)); 00230 si = 0.; 00231 00232 L340: 00233 i__1 = en; 00234 for (i__ = *low; i__ <= i__1; ++i__) { 00235 hr[i__ + i__ * hr_dim1] -= sr; 00236 hi[i__ + i__ * hi_dim1] -= si; 00237 /* L360: */ 00238 } 00239 00240 tr += sr; 00241 ti += si; 00242 ++its; 00243 --itn; 00244 /* .......... REDUCE TO TRIANGLE (ROWS) .......... */ 00245 lp1 = l + 1; 00246 00247 i__1 = en; 00248 for (i__ = lp1; i__ <= i__1; ++i__) { 00249 sr = hr[i__ + (i__ - 1) * hr_dim1]; 00250 hr[i__ + (i__ - 1) * hr_dim1] = 0.; 00251 d__1 = pythag_(&hr[i__ - 1 + (i__ - 1) * hr_dim1], &hi[i__ - 1 + (i__ 00252 - 1) * hi_dim1]); 00253 norm = pythag_(&d__1, &sr); 00254 xr = hr[i__ - 1 + (i__ - 1) * hr_dim1] / norm; 00255 wr[i__ - 1] = xr; 00256 xi = hi[i__ - 1 + (i__ - 1) * hi_dim1] / norm; 00257 wi[i__ - 1] = xi; 00258 hr[i__ - 1 + (i__ - 1) * hr_dim1] = norm; 00259 hi[i__ - 1 + (i__ - 1) * hi_dim1] = 0.; 00260 hi[i__ + (i__ - 1) * hi_dim1] = sr / norm; 00261 00262 i__2 = en; 00263 for (j = i__; j <= i__2; ++j) { 00264 yr = hr[i__ - 1 + j * hr_dim1]; 00265 yi = hi[i__ - 1 + j * hi_dim1]; 00266 zzr = hr[i__ + j * hr_dim1]; 00267 zzi = hi[i__ + j * hi_dim1]; 00268 hr[i__ - 1 + j * hr_dim1] = xr * yr + xi * yi + hi[i__ + (i__ - 1) 00269 * hi_dim1] * zzr; 00270 hi[i__ - 1 + j * hi_dim1] = xr * yi - xi * yr + hi[i__ + (i__ - 1) 00271 * hi_dim1] * zzi; 00272 hr[i__ + j * hr_dim1] = xr * zzr - xi * zzi - hi[i__ + (i__ - 1) * 00273 hi_dim1] * yr; 00274 hi[i__ + j * hi_dim1] = xr * zzi + xi * zzr - hi[i__ + (i__ - 1) * 00275 hi_dim1] * yi; 00276 /* L490: */ 00277 } 00278 00279 /* L500: */ 00280 } 00281 00282 si = hi[en + en * hi_dim1]; 00283 if (si == 0.) { 00284 goto L540; 00285 } 00286 norm = pythag_(&hr[en + en * hr_dim1], &si); 00287 sr = hr[en + en * hr_dim1] / norm; 00288 si /= norm; 00289 hr[en + en * hr_dim1] = norm; 00290 hi[en + en * hi_dim1] = 0.; 00291 /* .......... INVERSE OPERATION (COLUMNS) .......... */ 00292 L540: 00293 i__1 = en; 00294 for (j = lp1; j <= i__1; ++j) { 00295 xr = wr[j - 1]; 00296 xi = wi[j - 1]; 00297 00298 i__2 = j; 00299 for (i__ = l; i__ <= i__2; ++i__) { 00300 yr = hr[i__ + (j - 1) * hr_dim1]; 00301 yi = 0.; 00302 zzr = hr[i__ + j * hr_dim1]; 00303 zzi = hi[i__ + j * hi_dim1]; 00304 if (i__ == j) { 00305 goto L560; 00306 } 00307 yi = hi[i__ + (j - 1) * hi_dim1]; 00308 hi[i__ + (j - 1) * hi_dim1] = xr * yi + xi * yr + hi[j + (j - 1) * 00309 hi_dim1] * zzi; 00310 L560: 00311 hr[i__ + (j - 1) * hr_dim1] = xr * yr - xi * yi + hi[j + (j - 1) * 00312 hi_dim1] * zzr; 00313 hr[i__ + j * hr_dim1] = xr * zzr + xi * zzi - hi[j + (j - 1) * 00314 hi_dim1] * yr; 00315 hi[i__ + j * hi_dim1] = xr * zzi - xi * zzr - hi[j + (j - 1) * 00316 hi_dim1] * yi; 00317 /* L580: */ 00318 } 00319 00320 /* L600: */ 00321 } 00322 00323 if (si == 0.) { 00324 goto L240; 00325 } 00326 00327 i__1 = en; 00328 for (i__ = l; i__ <= i__1; ++i__) { 00329 yr = hr[i__ + en * hr_dim1]; 00330 yi = hi[i__ + en * hi_dim1]; 00331 hr[i__ + en * hr_dim1] = sr * yr - si * yi; 00332 hi[i__ + en * hi_dim1] = sr * yi + si * yr; 00333 /* L630: */ 00334 } 00335 00336 goto L240; 00337 /* .......... A ROOT FOUND .......... */ 00338 L660: 00339 wr[en] = hr[en + en * hr_dim1] + tr; 00340 wi[en] = hi[en + en * hi_dim1] + ti; 00341 en = enm1; 00342 goto L220; 00343 /* .......... SET ERROR -- ALL EIGENVALUES HAVE NOT */ 00344 /* CONVERGED AFTER 30*N ITERATIONS .......... */ 00345 L1000: 00346 *ierr = en; 00347 L1001: 00348 return 0; 00349 } /* comqr_ */ |