slarrk.c
Go to the documentation of this file.
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_ */


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:56:11