00001 /* slarrk.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 /* Subroutine */ int slarrk_(integer *n, integer *iw, real *gl, real *gu, 00017 real *d__, real *e2, real *pivmin, real *reltol, real *w, real *werr, 00018 integer *info) 00019 { 00020 /* System generated locals */ 00021 integer i__1; 00022 real r__1, r__2; 00023 00024 /* Builtin functions */ 00025 double log(doublereal); 00026 00027 /* Local variables */ 00028 integer i__, it; 00029 real mid, eps, tmp1, tmp2, left, atoli, right; 00030 integer itmax; 00031 real rtoli, tnorm; 00032 extern doublereal slamch_(char *); 00033 integer negcnt; 00034 00035 00036 /* -- LAPACK auxiliary routine (version 3.2) -- */ 00037 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ 00038 /* November 2006 */ 00039 00040 /* .. Scalar Arguments .. */ 00041 /* .. */ 00042 /* .. Array Arguments .. */ 00043 /* .. */ 00044 00045 /* Purpose */ 00046 /* ======= */ 00047 00048 /* SLARRK computes one eigenvalue of a symmetric tridiagonal */ 00049 /* matrix T to suitable accuracy. This is an auxiliary code to be */ 00050 /* called from SSTEMR. */ 00051 00052 /* To avoid overflow, the matrix must be scaled so that its */ 00053 /* largest element is no greater than overflow**(1/2) * */ 00054 /* underflow**(1/4) in absolute value, and for greatest */ 00055 /* accuracy, it should not be much smaller than that. */ 00056 00057 /* See W. Kahan "Accurate Eigenvalues of a Symmetric Tridiagonal */ 00058 /* Matrix", Report CS41, Computer Science Dept., Stanford */ 00059 /* University, July 21, 1966. */ 00060 00061 /* Arguments */ 00062 /* ========= */ 00063 00064 /* N (input) INTEGER */ 00065 /* The order of the tridiagonal matrix T. N >= 0. */ 00066 00067 /* IW (input) INTEGER */ 00068 /* The index of the eigenvalues to be returned. */ 00069 00070 /* GL (input) REAL */ 00071 /* GU (input) REAL */ 00072 /* An upper and a lower bound on the eigenvalue. */ 00073 00074 /* D (input) REAL array, dimension (N) */ 00075 /* The n diagonal elements of the tridiagonal matrix T. */ 00076 00077 /* E2 (input) REAL array, dimension (N-1) */ 00078 /* The (n-1) squared off-diagonal elements of the tridiagonal matrix T. */ 00079 00080 /* PIVMIN (input) REAL */ 00081 /* The minimum pivot allowed in the Sturm sequence for T. */ 00082 00083 /* RELTOL (input) REAL */ 00084 /* The minimum relative width of an interval. When an interval */ 00085 /* is narrower than RELTOL times the larger (in */ 00086 /* magnitude) endpoint, then it is considered to be */ 00087 /* sufficiently small, i.e., converged. Note: this should */ 00088 /* always be at least radix*machine epsilon. */ 00089 00090 /* W (output) REAL */ 00091 00092 /* WERR (output) REAL */ 00093 /* The error bound on the corresponding eigenvalue approximation */ 00094 /* in W. */ 00095 00096 /* INFO (output) INTEGER */ 00097 /* = 0: Eigenvalue converged */ 00098 /* = -1: Eigenvalue did NOT converge */ 00099 00100 /* Internal Parameters */ 00101 /* =================== */ 00102 00103 /* FUDGE REAL , default = 2 */ 00104 /* A "fudge factor" to widen the Gershgorin intervals. */ 00105 00106 /* ===================================================================== */ 00107 00108 /* .. Parameters .. */ 00109 /* .. */ 00110 /* .. Local Scalars .. */ 00111 /* .. */ 00112 /* .. External Functions .. */ 00113 /* .. */ 00114 /* .. Intrinsic Functions .. */ 00115 /* .. */ 00116 /* .. Executable Statements .. */ 00117 00118 /* Get machine constants */ 00119 /* Parameter adjustments */ 00120 --e2; 00121 --d__; 00122 00123 /* Function Body */ 00124 eps = slamch_("P"); 00125 /* Computing MAX */ 00126 r__1 = dabs(*gl), r__2 = dabs(*gu); 00127 tnorm = dmax(r__1,r__2); 00128 rtoli = *reltol; 00129 atoli = *pivmin * 4.f; 00130 itmax = (integer) ((log(tnorm + *pivmin) - log(*pivmin)) / log(2.f)) + 2; 00131 *info = -1; 00132 left = *gl - tnorm * 2.f * eps * *n - *pivmin * 4.f; 00133 right = *gu + tnorm * 2.f * eps * *n + *pivmin * 4.f; 00134 it = 0; 00135 L10: 00136 00137 /* Check if interval converged or maximum number of iterations reached */ 00138 00139 tmp1 = (r__1 = right - left, dabs(r__1)); 00140 /* Computing MAX */ 00141 r__1 = dabs(right), r__2 = dabs(left); 00142 tmp2 = dmax(r__1,r__2); 00143 /* Computing MAX */ 00144 r__1 = max(atoli,*pivmin), r__2 = rtoli * tmp2; 00145 if (tmp1 < dmax(r__1,r__2)) { 00146 *info = 0; 00147 goto L30; 00148 } 00149 if (it > itmax) { 00150 goto L30; 00151 } 00152 00153 /* Count number of negative pivots for mid-point */ 00154 00155 ++it; 00156 mid = (left + right) * .5f; 00157 negcnt = 0; 00158 tmp1 = d__[1] - mid; 00159 if (dabs(tmp1) < *pivmin) { 00160 tmp1 = -(*pivmin); 00161 } 00162 if (tmp1 <= 0.f) { 00163 ++negcnt; 00164 } 00165 00166 i__1 = *n; 00167 for (i__ = 2; i__ <= i__1; ++i__) { 00168 tmp1 = d__[i__] - e2[i__ - 1] / tmp1 - mid; 00169 if (dabs(tmp1) < *pivmin) { 00170 tmp1 = -(*pivmin); 00171 } 00172 if (tmp1 <= 0.f) { 00173 ++negcnt; 00174 } 00175 /* L20: */ 00176 } 00177 if (negcnt >= *iw) { 00178 right = mid; 00179 } else { 00180 left = mid; 00181 } 00182 goto L10; 00183 L30: 00184 00185 /* Converged or maximum number of iterations reached */ 00186 00187 *w = (left + right) * .5f; 00188 *werr = (r__1 = right - left, dabs(r__1)) * .5f; 00189 return 0; 00190 00191 /* End of SLARRK */ 00192 00193 } /* slarrk_ */