Doxygen Source Code Documentation
eis_bqr.c File Reference
#include "f2c.h"
Go to the source code of this file.
Functions | |
int | bqr_ (integer *nm, integer *n, integer *mb, doublereal *a, doublereal *t, doublereal *r__, integer *ierr, integer *nv, doublereal *rv) |
Variables | |
doublereal | c_b8 = 1. |
Function Documentation
|
Definition at line 12 of file eis_bqr.c. References a, abs, c_b8, d_sign(), l, m1, m2, max, min, pythag_(), q, and scale.
00015 { 00016 /* System generated locals */ 00017 integer a_dim1, a_offset, i__1, i__2, i__3; 00018 doublereal d__1; 00019 00020 /* Builtin functions */ 00021 double d_sign(doublereal *, doublereal *), sqrt(doublereal); 00022 00023 /* Local variables */ 00024 static doublereal f, g; 00025 static integer i__, j, k, l, m; 00026 static doublereal q, s, scale; 00027 static integer imult, m1, m2, m3, m4, m21, m31, ii, ik, jk, kj, jm, kk, 00028 km, ll, mk, mn, ni, mz; 00029 extern doublereal pythag_(doublereal *, doublereal *); 00030 static integer kj1, its; 00031 static doublereal tst1, tst2; 00032 00033 00034 00035 /* THIS SUBROUTINE IS A TRANSLATION OF THE ALGOL PROCEDURE BQR, */ 00036 /* NUM. MATH. 16, 85-92(1970) BY MARTIN, REINSCH, AND WILKINSON. */ 00037 /* HANDBOOK FOR AUTO. COMP., VOL II-LINEAR ALGEBRA, 266-272(1971). */ 00038 00039 /* THIS SUBROUTINE FINDS THE EIGENVALUE OF SMALLEST (USUALLY) */ 00040 /* MAGNITUDE OF A REAL SYMMETRIC BAND MATRIX USING THE */ 00041 /* QR ALGORITHM WITH SHIFTS OF ORIGIN. CONSECUTIVE CALLS */ 00042 /* CAN BE MADE TO FIND FURTHER EIGENVALUES. */ 00043 00044 /* ON INPUT */ 00045 00046 /* NM MUST BE SET TO THE ROW DIMENSION OF TWO-DIMENSIONAL */ 00047 /* ARRAY PARAMETERS AS DECLARED IN THE CALLING PROGRAM */ 00048 /* DIMENSION STATEMENT. */ 00049 00050 /* N IS THE ORDER OF THE MATRIX. */ 00051 00052 /* MB IS THE (HALF) BAND WIDTH OF THE MATRIX, DEFINED AS THE */ 00053 /* NUMBER OF ADJACENT DIAGONALS, INCLUDING THE PRINCIPAL */ 00054 /* DIAGONAL, REQUIRED TO SPECIFY THE NON-ZERO PORTION OF THE */ 00055 /* LOWER TRIANGLE OF THE MATRIX. */ 00056 00057 /* A CONTAINS THE LOWER TRIANGLE OF THE SYMMETRIC BAND INPUT */ 00058 /* MATRIX STORED AS AN N BY MB ARRAY. ITS LOWEST SUBDIAGONAL */ 00059 /* IS STORED IN THE LAST N+1-MB POSITIONS OF THE FIRST COLUMN, */ 00060 /* ITS NEXT SUBDIAGONAL IN THE LAST N+2-MB POSITIONS OF THE */ 00061 /* SECOND COLUMN, FURTHER SUBDIAGONALS SIMILARLY, AND FINALLY */ 00062 /* ITS PRINCIPAL DIAGONAL IN THE N POSITIONS OF THE LAST COLUMN. 00063 */ 00064 /* CONTENTS OF STORAGES NOT PART OF THE MATRIX ARE ARBITRARY. */ 00065 /* ON A SUBSEQUENT CALL, ITS OUTPUT CONTENTS FROM THE PREVIOUS */ 00066 /* CALL SHOULD BE PASSED. */ 00067 00068 /* T SPECIFIES THE SHIFT (OF EIGENVALUES) APPLIED TO THE DIAGONAL 00069 */ 00070 /* OF A IN FORMING THE INPUT MATRIX. WHAT IS ACTUALLY DETERMINED 00071 */ 00072 /* IS THE EIGENVALUE OF A+TI (I IS THE IDENTITY MATRIX) NEAREST 00073 */ 00074 /* TO T. ON A SUBSEQUENT CALL, THE OUTPUT VALUE OF T FROM THE */ 00075 /* PREVIOUS CALL SHOULD BE PASSED IF THE NEXT NEAREST EIGENVALUE 00076 */ 00077 /* IS SOUGHT. */ 00078 00079 /* R SHOULD BE SPECIFIED AS ZERO ON THE FIRST CALL, AND AS ITS */ 00080 /* OUTPUT VALUE FROM THE PREVIOUS CALL ON A SUBSEQUENT CALL. */ 00081 /* IT IS USED TO DETERMINE WHEN THE LAST ROW AND COLUMN OF */ 00082 /* THE TRANSFORMED BAND MATRIX CAN BE REGARDED AS NEGLIGIBLE. */ 00083 00084 /* NV MUST BE SET TO THE DIMENSION OF THE ARRAY PARAMETER RV */ 00085 /* AS DECLARED IN THE CALLING PROGRAM DIMENSION STATEMENT. */ 00086 00087 /* ON OUTPUT */ 00088 00089 /* A CONTAINS THE TRANSFORMED BAND MATRIX. THE MATRIX A+TI */ 00090 /* DERIVED FROM THE OUTPUT PARAMETERS IS SIMILAR TO THE */ 00091 /* INPUT A+TI TO WITHIN ROUNDING ERRORS. ITS LAST ROW AND */ 00092 /* COLUMN ARE NULL (IF IERR IS ZERO). */ 00093 00094 /* T CONTAINS THE COMPUTED EIGENVALUE OF A+TI (IF IERR IS ZERO). */ 00095 00096 /* R CONTAINS THE MAXIMUM OF ITS INPUT VALUE AND THE NORM OF THE */ 00097 /* LAST COLUMN OF THE INPUT MATRIX A. */ 00098 00099 /* IERR IS SET TO */ 00100 /* ZERO FOR NORMAL RETURN, */ 00101 /* N IF THE EIGENVALUE HAS NOT BEEN */ 00102 /* DETERMINED AFTER 30 ITERATIONS. */ 00103 00104 /* RV IS A TEMPORARY STORAGE ARRAY OF DIMENSION AT LEAST */ 00105 /* (2*MB**2+4*MB-3). THE FIRST (3*MB-2) LOCATIONS CORRESPOND */ 00106 /* TO THE ALGOL ARRAY B, THE NEXT (2*MB-1) LOCATIONS CORRESPOND 00107 */ 00108 /* TO THE ALGOL ARRAY H, AND THE FINAL (2*MB**2-MB) LOCATIONS */ 00109 /* CORRESPOND TO THE MB BY (2*MB-1) ALGOL ARRAY U. */ 00110 00111 /* NOTE. FOR A SUBSEQUENT CALL, N SHOULD BE REPLACED BY N-1, BUT */ 00112 /* MB SHOULD NOT BE ALTERED EVEN WHEN IT EXCEEDS THE CURRENT N. */ 00113 00114 /* CALLS PYTHAG FOR DSQRT(A*A + B*B) . */ 00115 00116 /* QUESTIONS AND COMMENTS SHOULD BE DIRECTED TO BURTON S. GARBOW, */ 00117 /* MATHEMATICS AND COMPUTER SCIENCE DIV, ARGONNE NATIONAL LABORATORY 00118 */ 00119 00120 /* THIS VERSION DATED AUGUST 1983. */ 00121 00122 /* ------------------------------------------------------------------ 00123 */ 00124 00125 /* Parameter adjustments */ 00126 a_dim1 = *nm; 00127 a_offset = a_dim1 + 1; 00128 a -= a_offset; 00129 --rv; 00130 00131 /* Function Body */ 00132 *ierr = 0; 00133 m1 = min(*mb,*n); 00134 m = m1 - 1; 00135 m2 = m + m; 00136 m21 = m2 + 1; 00137 m3 = m21 + m; 00138 m31 = m3 + 1; 00139 m4 = m31 + m2; 00140 mn = m + *n; 00141 mz = *mb - m1; 00142 its = 0; 00143 /* .......... TEST FOR CONVERGENCE .......... */ 00144 L40: 00145 g = a[*n + *mb * a_dim1]; 00146 if (m == 0) { 00147 goto L360; 00148 } 00149 f = 0.; 00150 00151 i__1 = m; 00152 for (k = 1; k <= i__1; ++k) { 00153 mk = k + mz; 00154 f += (d__1 = a[*n + mk * a_dim1], abs(d__1)); 00155 /* L50: */ 00156 } 00157 00158 if (its == 0 && f > *r__) { 00159 *r__ = f; 00160 } 00161 tst1 = *r__; 00162 tst2 = tst1 + f; 00163 if (tst2 <= tst1) { 00164 goto L360; 00165 } 00166 if (its == 30) { 00167 goto L1000; 00168 } 00169 ++its; 00170 /* .......... FORM SHIFT FROM BOTTOM 2 BY 2 MINOR .......... */ 00171 if (f > *r__ * .25 && its < 5) { 00172 goto L90; 00173 } 00174 f = a[*n + (*mb - 1) * a_dim1]; 00175 if (f == 0.) { 00176 goto L70; 00177 } 00178 q = (a[*n - 1 + *mb * a_dim1] - g) / (f * 2.); 00179 s = pythag_(&q, &c_b8); 00180 g -= f / (q + d_sign(&s, &q)); 00181 L70: 00182 *t += g; 00183 00184 i__1 = *n; 00185 for (i__ = 1; i__ <= i__1; ++i__) { 00186 /* L80: */ 00187 a[i__ + *mb * a_dim1] -= g; 00188 } 00189 00190 L90: 00191 i__1 = m4; 00192 for (k = m31; k <= i__1; ++k) { 00193 /* L100: */ 00194 rv[k] = 0.; 00195 } 00196 00197 i__1 = mn; 00198 for (ii = 1; ii <= i__1; ++ii) { 00199 i__ = ii - m; 00200 ni = *n - ii; 00201 if (ni < 0) { 00202 goto L230; 00203 } 00204 /* .......... FORM COLUMN OF SHIFTED MATRIX A-G*I .......... */ 00205 /* Computing MAX */ 00206 i__2 = 1, i__3 = 2 - i__; 00207 l = max(i__2,i__3); 00208 00209 i__2 = m3; 00210 for (k = 1; k <= i__2; ++k) { 00211 /* L110: */ 00212 rv[k] = 0.; 00213 } 00214 00215 i__2 = m1; 00216 for (k = l; k <= i__2; ++k) { 00217 km = k + m; 00218 mk = k + mz; 00219 rv[km] = a[ii + mk * a_dim1]; 00220 /* L120: */ 00221 } 00222 00223 ll = min(m,ni); 00224 if (ll == 0) { 00225 goto L135; 00226 } 00227 00228 i__2 = ll; 00229 for (k = 1; k <= i__2; ++k) { 00230 km = k + m21; 00231 ik = ii + k; 00232 mk = *mb - k; 00233 rv[km] = a[ik + mk * a_dim1]; 00234 /* L130: */ 00235 } 00236 /* .......... PRE-MULTIPLY WITH HOUSEHOLDER REFLECTIONS .......... 00237 */ 00238 L135: 00239 ll = m2; 00240 imult = 0; 00241 /* .......... MULTIPLICATION PROCEDURE .......... */ 00242 L140: 00243 kj = m4 - m1; 00244 00245 i__2 = ll; 00246 for (j = 1; j <= i__2; ++j) { 00247 kj += m1; 00248 jm = j + m3; 00249 if (rv[jm] == 0.) { 00250 goto L170; 00251 } 00252 f = 0.; 00253 00254 i__3 = m1; 00255 for (k = 1; k <= i__3; ++k) { 00256 ++kj; 00257 jk = j + k - 1; 00258 f += rv[kj] * rv[jk]; 00259 /* L150: */ 00260 } 00261 00262 f /= rv[jm]; 00263 kj -= m1; 00264 00265 i__3 = m1; 00266 for (k = 1; k <= i__3; ++k) { 00267 ++kj; 00268 jk = j + k - 1; 00269 rv[jk] -= rv[kj] * f; 00270 /* L160: */ 00271 } 00272 00273 kj -= m1; 00274 L170: 00275 ; 00276 } 00277 00278 if (imult != 0) { 00279 goto L280; 00280 } 00281 /* .......... HOUSEHOLDER REFLECTION .......... */ 00282 f = rv[m21]; 00283 s = 0.; 00284 rv[m4] = 0.; 00285 scale = 0.; 00286 00287 i__2 = m3; 00288 for (k = m21; k <= i__2; ++k) { 00289 /* L180: */ 00290 scale += (d__1 = rv[k], abs(d__1)); 00291 } 00292 00293 if (scale == 0.) { 00294 goto L210; 00295 } 00296 00297 i__2 = m3; 00298 for (k = m21; k <= i__2; ++k) { 00299 /* L190: */ 00300 /* Computing 2nd power */ 00301 d__1 = rv[k] / scale; 00302 s += d__1 * d__1; 00303 } 00304 00305 s = scale * scale * s; 00306 d__1 = sqrt(s); 00307 g = -d_sign(&d__1, &f); 00308 rv[m21] = g; 00309 rv[m4] = s - f * g; 00310 kj = m4 + m2 * m1 + 1; 00311 rv[kj] = f - g; 00312 00313 i__2 = m1; 00314 for (k = 2; k <= i__2; ++k) { 00315 ++kj; 00316 km = k + m2; 00317 rv[kj] = rv[km]; 00318 /* L200: */ 00319 } 00320 /* .......... SAVE COLUMN OF TRIANGULAR FACTOR R .......... */ 00321 L210: 00322 i__2 = m1; 00323 for (k = l; k <= i__2; ++k) { 00324 km = k + m; 00325 mk = k + mz; 00326 a[ii + mk * a_dim1] = rv[km]; 00327 /* L220: */ 00328 } 00329 00330 L230: 00331 /* Computing MAX */ 00332 i__2 = 1, i__3 = m1 + 1 - i__; 00333 l = max(i__2,i__3); 00334 if (i__ <= 0) { 00335 goto L300; 00336 } 00337 /* .......... PERFORM ADDITIONAL STEPS .......... */ 00338 i__2 = m21; 00339 for (k = 1; k <= i__2; ++k) { 00340 /* L240: */ 00341 rv[k] = 0.; 00342 } 00343 00344 /* Computing MIN */ 00345 i__2 = m1, i__3 = ni + m1; 00346 ll = min(i__2,i__3); 00347 /* .......... GET ROW OF TRIANGULAR FACTOR R .......... */ 00348 i__2 = ll; 00349 for (kk = 1; kk <= i__2; ++kk) { 00350 k = kk - 1; 00351 km = k + m1; 00352 ik = i__ + k; 00353 mk = *mb - k; 00354 rv[km] = a[ik + mk * a_dim1]; 00355 /* L250: */ 00356 } 00357 /* .......... POST-MULTIPLY WITH HOUSEHOLDER REFLECTIONS ......... 00358 . */ 00359 ll = m1; 00360 imult = 1; 00361 goto L140; 00362 /* .......... STORE COLUMN OF NEW A MATRIX .......... */ 00363 L280: 00364 i__2 = m1; 00365 for (k = l; k <= i__2; ++k) { 00366 mk = k + mz; 00367 a[i__ + mk * a_dim1] = rv[k]; 00368 /* L290: */ 00369 } 00370 /* .......... UPDATE HOUSEHOLDER REFLECTIONS .......... */ 00371 L300: 00372 if (l > 1) { 00373 --l; 00374 } 00375 kj1 = m4 + l * m1; 00376 00377 i__2 = m2; 00378 for (j = l; j <= i__2; ++j) { 00379 jm = j + m3; 00380 rv[jm] = rv[jm + 1]; 00381 00382 i__3 = m1; 00383 for (k = 1; k <= i__3; ++k) { 00384 ++kj1; 00385 kj = kj1 - m1; 00386 rv[kj] = rv[kj1]; 00387 /* L320: */ 00388 } 00389 } 00390 00391 /* L350: */ 00392 } 00393 00394 goto L40; 00395 /* .......... CONVERGENCE .......... */ 00396 L360: 00397 *t += g; 00398 00399 i__1 = *n; 00400 for (i__ = 1; i__ <= i__1; ++i__) { 00401 /* L380: */ 00402 a[i__ + *mb * a_dim1] -= g; 00403 } 00404 00405 i__1 = m1; 00406 for (k = 1; k <= i__1; ++k) { 00407 mk = k + mz; 00408 a[*n + mk * a_dim1] = 0.; 00409 /* L400: */ 00410 } 00411 00412 goto L1001; 00413 /* .......... SET ERROR -- NO CONVERGENCE TO */ 00414 /* EIGENVALUE AFTER 30 ITERATIONS .......... */ 00415 L1000: 00416 *ierr = *n; 00417 L1001: 00418 return 0; 00419 } /* bqr_ */ |
Variable Documentation
|
Definition at line 10 of file eis_bqr.c. Referenced by bqr_(). |