dstebz.c
Go to the documentation of this file.
00001 /* dstebz.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 integer c__1 = 1;
00019 static integer c_n1 = -1;
00020 static integer c__3 = 3;
00021 static integer c__2 = 2;
00022 static integer c__0 = 0;
00023 
00024 /* Subroutine */ int dstebz_(char *range, char *order, integer *n, doublereal 
00025         *vl, doublereal *vu, integer *il, integer *iu, doublereal *abstol, 
00026         doublereal *d__, doublereal *e, integer *m, integer *nsplit, 
00027         doublereal *w, integer *iblock, integer *isplit, doublereal *work, 
00028         integer *iwork, integer *info)
00029 {
00030     /* System generated locals */
00031     integer i__1, i__2, i__3;
00032     doublereal d__1, d__2, d__3, d__4, d__5;
00033 
00034     /* Builtin functions */
00035     double sqrt(doublereal), log(doublereal);
00036 
00037     /* Local variables */
00038     integer j, ib, jb, ie, je, nb;
00039     doublereal gl;
00040     integer im, in;
00041     doublereal gu;
00042     integer iw;
00043     doublereal wl, wu;
00044     integer nwl;
00045     doublereal ulp, wlu, wul;
00046     integer nwu;
00047     doublereal tmp1, tmp2;
00048     integer iend, ioff, iout, itmp1, jdisc;
00049     extern logical lsame_(char *, char *);
00050     integer iinfo;
00051     doublereal atoli;
00052     integer iwoff;
00053     doublereal bnorm;
00054     integer itmax;
00055     doublereal wkill, rtoli, tnorm;
00056     extern doublereal dlamch_(char *);
00057     integer ibegin;
00058     extern /* Subroutine */ int dlaebz_(integer *, integer *, integer *, 
00059             integer *, integer *, integer *, doublereal *, doublereal *, 
00060             doublereal *, doublereal *, doublereal *, doublereal *, integer *, 
00061              doublereal *, doublereal *, integer *, integer *, doublereal *, 
00062             integer *, integer *);
00063     integer irange, idiscl;
00064     doublereal safemn;
00065     integer idumma[1];
00066     extern /* Subroutine */ int xerbla_(char *, integer *);
00067     extern integer ilaenv_(integer *, char *, char *, integer *, integer *, 
00068             integer *, integer *);
00069     integer idiscu, iorder;
00070     logical ncnvrg;
00071     doublereal pivmin;
00072     logical toofew;
00073 
00074 
00075 /*  -- LAPACK routine (version 3.2) -- */
00076 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00077 /*     November 2006 */
00078 /*     8-18-00:  Increase FUDGE factor for T3E (eca) */
00079 
00080 /*     .. Scalar Arguments .. */
00081 /*     .. */
00082 /*     .. Array Arguments .. */
00083 /*     .. */
00084 
00085 /*  Purpose */
00086 /*  ======= */
00087 
00088 /*  DSTEBZ computes the eigenvalues of a symmetric tridiagonal */
00089 /*  matrix T.  The user may ask for all eigenvalues, all eigenvalues */
00090 /*  in the half-open interval (VL, VU], or the IL-th through IU-th */
00091 /*  eigenvalues. */
00092 
00093 /*  To avoid overflow, the matrix must be scaled so that its */
00094 /*  largest element is no greater than overflow**(1/2) * */
00095 /*  underflow**(1/4) in absolute value, and for greatest */
00096 /*  accuracy, it should not be much smaller than that. */
00097 
00098 /*  See W. Kahan "Accurate Eigenvalues of a Symmetric Tridiagonal */
00099 /*  Matrix", Report CS41, Computer Science Dept., Stanford */
00100 /*  University, July 21, 1966. */
00101 
00102 /*  Arguments */
00103 /*  ========= */
00104 
00105 /*  RANGE   (input) CHARACTER*1 */
00106 /*          = 'A': ("All")   all eigenvalues will be found. */
00107 /*          = 'V': ("Value") all eigenvalues in the half-open interval */
00108 /*                           (VL, VU] will be found. */
00109 /*          = 'I': ("Index") the IL-th through IU-th eigenvalues (of the */
00110 /*                           entire matrix) will be found. */
00111 
00112 /*  ORDER   (input) CHARACTER*1 */
00113 /*          = 'B': ("By Block") the eigenvalues will be grouped by */
00114 /*                              split-off block (see IBLOCK, ISPLIT) and */
00115 /*                              ordered from smallest to largest within */
00116 /*                              the block. */
00117 /*          = 'E': ("Entire matrix") */
00118 /*                              the eigenvalues for the entire matrix */
00119 /*                              will be ordered from smallest to */
00120 /*                              largest. */
00121 
00122 /*  N       (input) INTEGER */
00123 /*          The order of the tridiagonal matrix T.  N >= 0. */
00124 
00125 /*  VL      (input) DOUBLE PRECISION */
00126 /*  VU      (input) DOUBLE PRECISION */
00127 /*          If RANGE='V', the lower and upper bounds of the interval to */
00128 /*          be searched for eigenvalues.  Eigenvalues less than or equal */
00129 /*          to VL, or greater than VU, will not be returned.  VL < VU. */
00130 /*          Not referenced if RANGE = 'A' or 'I'. */
00131 
00132 /*  IL      (input) INTEGER */
00133 /*  IU      (input) INTEGER */
00134 /*          If RANGE='I', the indices (in ascending order) of the */
00135 /*          smallest and largest eigenvalues to be returned. */
00136 /*          1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0. */
00137 /*          Not referenced if RANGE = 'A' or 'V'. */
00138 
00139 /*  ABSTOL  (input) DOUBLE PRECISION */
00140 /*          The absolute tolerance for the eigenvalues.  An eigenvalue */
00141 /*          (or cluster) is considered to be located if it has been */
00142 /*          determined to lie in an interval whose width is ABSTOL or */
00143 /*          less.  If ABSTOL is less than or equal to zero, then ULP*|T| */
00144 /*          will be used, where |T| means the 1-norm of T. */
00145 
00146 /*          Eigenvalues will be computed most accurately when ABSTOL is */
00147 /*          set to twice the underflow threshold 2*DLAMCH('S'), not zero. */
00148 
00149 /*  D       (input) DOUBLE PRECISION array, dimension (N) */
00150 /*          The n diagonal elements of the tridiagonal matrix T. */
00151 
00152 /*  E       (input) DOUBLE PRECISION array, dimension (N-1) */
00153 /*          The (n-1) off-diagonal elements of the tridiagonal matrix T. */
00154 
00155 /*  M       (output) INTEGER */
00156 /*          The actual number of eigenvalues found. 0 <= M <= N. */
00157 /*          (See also the description of INFO=2,3.) */
00158 
00159 /*  NSPLIT  (output) INTEGER */
00160 /*          The number of diagonal blocks in the matrix T. */
00161 /*          1 <= NSPLIT <= N. */
00162 
00163 /*  W       (output) DOUBLE PRECISION array, dimension (N) */
00164 /*          On exit, the first M elements of W will contain the */
00165 /*          eigenvalues.  (DSTEBZ may use the remaining N-M elements as */
00166 /*          workspace.) */
00167 
00168 /*  IBLOCK  (output) INTEGER array, dimension (N) */
00169 /*          At each row/column j where E(j) is zero or small, the */
00170 /*          matrix T is considered to split into a block diagonal */
00171 /*          matrix.  On exit, if INFO = 0, IBLOCK(i) specifies to which */
00172 /*          block (from 1 to the number of blocks) the eigenvalue W(i) */
00173 /*          belongs.  (DSTEBZ may use the remaining N-M elements as */
00174 /*          workspace.) */
00175 
00176 /*  ISPLIT  (output) INTEGER array, dimension (N) */
00177 /*          The splitting points, at which T breaks up into submatrices. */
00178 /*          The first submatrix consists of rows/columns 1 to ISPLIT(1), */
00179 /*          the second of rows/columns ISPLIT(1)+1 through ISPLIT(2), */
00180 /*          etc., and the NSPLIT-th consists of rows/columns */
00181 /*          ISPLIT(NSPLIT-1)+1 through ISPLIT(NSPLIT)=N. */
00182 /*          (Only the first NSPLIT elements will actually be used, but */
00183 /*          since the user cannot know a priori what value NSPLIT will */
00184 /*          have, N words must be reserved for ISPLIT.) */
00185 
00186 /*  WORK    (workspace) DOUBLE PRECISION array, dimension (4*N) */
00187 
00188 /*  IWORK   (workspace) INTEGER array, dimension (3*N) */
00189 
00190 /*  INFO    (output) INTEGER */
00191 /*          = 0:  successful exit */
00192 /*          < 0:  if INFO = -i, the i-th argument had an illegal value */
00193 /*          > 0:  some or all of the eigenvalues failed to converge or */
00194 /*                were not computed: */
00195 /*                =1 or 3: Bisection failed to converge for some */
00196 /*                        eigenvalues; these eigenvalues are flagged by a */
00197 /*                        negative block number.  The effect is that the */
00198 /*                        eigenvalues may not be as accurate as the */
00199 /*                        absolute and relative tolerances.  This is */
00200 /*                        generally caused by unexpectedly inaccurate */
00201 /*                        arithmetic. */
00202 /*                =2 or 3: RANGE='I' only: Not all of the eigenvalues */
00203 /*                        IL:IU were found. */
00204 /*                        Effect: M < IU+1-IL */
00205 /*                        Cause:  non-monotonic arithmetic, causing the */
00206 /*                                Sturm sequence to be non-monotonic. */
00207 /*                        Cure:   recalculate, using RANGE='A', and pick */
00208 /*                                out eigenvalues IL:IU.  In some cases, */
00209 /*                                increasing the PARAMETER "FUDGE" may */
00210 /*                                make things work. */
00211 /*                = 4:    RANGE='I', and the Gershgorin interval */
00212 /*                        initially used was too small.  No eigenvalues */
00213 /*                        were computed. */
00214 /*                        Probable cause: your machine has sloppy */
00215 /*                                        floating-point arithmetic. */
00216 /*                        Cure: Increase the PARAMETER "FUDGE", */
00217 /*                              recompile, and try again. */
00218 
00219 /*  Internal Parameters */
00220 /*  =================== */
00221 
00222 /*  RELFAC  DOUBLE PRECISION, default = 2.0e0 */
00223 /*          The relative tolerance.  An interval (a,b] lies within */
00224 /*          "relative tolerance" if  b-a < RELFAC*ulp*max(|a|,|b|), */
00225 /*          where "ulp" is the machine precision (distance from 1 to */
00226 /*          the next larger floating point number.) */
00227 
00228 /*  FUDGE   DOUBLE PRECISION, default = 2 */
00229 /*          A "fudge factor" to widen the Gershgorin intervals.  Ideally, */
00230 /*          a value of 1 should work, but on machines with sloppy */
00231 /*          arithmetic, this needs to be larger.  The default for */
00232 /*          publicly released versions should be large enough to handle */
00233 /*          the worst machine around.  Note that this has no effect */
00234 /*          on accuracy of the solution. */
00235 
00236 /*  ===================================================================== */
00237 
00238 /*     .. Parameters .. */
00239 /*     .. */
00240 /*     .. Local Scalars .. */
00241 /*     .. */
00242 /*     .. Local Arrays .. */
00243 /*     .. */
00244 /*     .. External Functions .. */
00245 /*     .. */
00246 /*     .. External Subroutines .. */
00247 /*     .. */
00248 /*     .. Intrinsic Functions .. */
00249 /*     .. */
00250 /*     .. Executable Statements .. */
00251 
00252     /* Parameter adjustments */
00253     --iwork;
00254     --work;
00255     --isplit;
00256     --iblock;
00257     --w;
00258     --e;
00259     --d__;
00260 
00261     /* Function Body */
00262     *info = 0;
00263 
00264 /*     Decode RANGE */
00265 
00266     if (lsame_(range, "A")) {
00267         irange = 1;
00268     } else if (lsame_(range, "V")) {
00269         irange = 2;
00270     } else if (lsame_(range, "I")) {
00271         irange = 3;
00272     } else {
00273         irange = 0;
00274     }
00275 
00276 /*     Decode ORDER */
00277 
00278     if (lsame_(order, "B")) {
00279         iorder = 2;
00280     } else if (lsame_(order, "E")) {
00281         iorder = 1;
00282     } else {
00283         iorder = 0;
00284     }
00285 
00286 /*     Check for Errors */
00287 
00288     if (irange <= 0) {
00289         *info = -1;
00290     } else if (iorder <= 0) {
00291         *info = -2;
00292     } else if (*n < 0) {
00293         *info = -3;
00294     } else if (irange == 2) {
00295         if (*vl >= *vu) {
00296             *info = -5;
00297         }
00298     } else if (irange == 3 && (*il < 1 || *il > max(1,*n))) {
00299         *info = -6;
00300     } else if (irange == 3 && (*iu < min(*n,*il) || *iu > *n)) {
00301         *info = -7;
00302     }
00303 
00304     if (*info != 0) {
00305         i__1 = -(*info);
00306         xerbla_("DSTEBZ", &i__1);
00307         return 0;
00308     }
00309 
00310 /*     Initialize error flags */
00311 
00312     *info = 0;
00313     ncnvrg = FALSE_;
00314     toofew = FALSE_;
00315 
00316 /*     Quick return if possible */
00317 
00318     *m = 0;
00319     if (*n == 0) {
00320         return 0;
00321     }
00322 
00323 /*     Simplifications: */
00324 
00325     if (irange == 3 && *il == 1 && *iu == *n) {
00326         irange = 1;
00327     }
00328 
00329 /*     Get machine constants */
00330 /*     NB is the minimum vector length for vector bisection, or 0 */
00331 /*     if only scalar is to be done. */
00332 
00333     safemn = dlamch_("S");
00334     ulp = dlamch_("P");
00335     rtoli = ulp * 2.;
00336     nb = ilaenv_(&c__1, "DSTEBZ", " ", n, &c_n1, &c_n1, &c_n1);
00337     if (nb <= 1) {
00338         nb = 0;
00339     }
00340 
00341 /*     Special Case when N=1 */
00342 
00343     if (*n == 1) {
00344         *nsplit = 1;
00345         isplit[1] = 1;
00346         if (irange == 2 && (*vl >= d__[1] || *vu < d__[1])) {
00347             *m = 0;
00348         } else {
00349             w[1] = d__[1];
00350             iblock[1] = 1;
00351             *m = 1;
00352         }
00353         return 0;
00354     }
00355 
00356 /*     Compute Splitting Points */
00357 
00358     *nsplit = 1;
00359     work[*n] = 0.;
00360     pivmin = 1.;
00361 
00362 /* DIR$ NOVECTOR */
00363     i__1 = *n;
00364     for (j = 2; j <= i__1; ++j) {
00365 /* Computing 2nd power */
00366         d__1 = e[j - 1];
00367         tmp1 = d__1 * d__1;
00368 /* Computing 2nd power */
00369         d__2 = ulp;
00370         if ((d__1 = d__[j] * d__[j - 1], abs(d__1)) * (d__2 * d__2) + safemn 
00371                 > tmp1) {
00372             isplit[*nsplit] = j - 1;
00373             ++(*nsplit);
00374             work[j - 1] = 0.;
00375         } else {
00376             work[j - 1] = tmp1;
00377             pivmin = max(pivmin,tmp1);
00378         }
00379 /* L10: */
00380     }
00381     isplit[*nsplit] = *n;
00382     pivmin *= safemn;
00383 
00384 /*     Compute Interval and ATOLI */
00385 
00386     if (irange == 3) {
00387 
00388 /*        RANGE='I': Compute the interval containing eigenvalues */
00389 /*                   IL through IU. */
00390 
00391 /*        Compute Gershgorin interval for entire (split) matrix */
00392 /*        and use it as the initial interval */
00393 
00394         gu = d__[1];
00395         gl = d__[1];
00396         tmp1 = 0.;
00397 
00398         i__1 = *n - 1;
00399         for (j = 1; j <= i__1; ++j) {
00400             tmp2 = sqrt(work[j]);
00401 /* Computing MAX */
00402             d__1 = gu, d__2 = d__[j] + tmp1 + tmp2;
00403             gu = max(d__1,d__2);
00404 /* Computing MIN */
00405             d__1 = gl, d__2 = d__[j] - tmp1 - tmp2;
00406             gl = min(d__1,d__2);
00407             tmp1 = tmp2;
00408 /* L20: */
00409         }
00410 
00411 /* Computing MAX */
00412         d__1 = gu, d__2 = d__[*n] + tmp1;
00413         gu = max(d__1,d__2);
00414 /* Computing MIN */
00415         d__1 = gl, d__2 = d__[*n] - tmp1;
00416         gl = min(d__1,d__2);
00417 /* Computing MAX */
00418         d__1 = abs(gl), d__2 = abs(gu);
00419         tnorm = max(d__1,d__2);
00420         gl = gl - tnorm * 2.1 * ulp * *n - pivmin * 4.2000000000000002;
00421         gu = gu + tnorm * 2.1 * ulp * *n + pivmin * 2.1;
00422 
00423 /*        Compute Iteration parameters */
00424 
00425         itmax = (integer) ((log(tnorm + pivmin) - log(pivmin)) / log(2.)) + 2;
00426         if (*abstol <= 0.) {
00427             atoli = ulp * tnorm;
00428         } else {
00429             atoli = *abstol;
00430         }
00431 
00432         work[*n + 1] = gl;
00433         work[*n + 2] = gl;
00434         work[*n + 3] = gu;
00435         work[*n + 4] = gu;
00436         work[*n + 5] = gl;
00437         work[*n + 6] = gu;
00438         iwork[1] = -1;
00439         iwork[2] = -1;
00440         iwork[3] = *n + 1;
00441         iwork[4] = *n + 1;
00442         iwork[5] = *il - 1;
00443         iwork[6] = *iu;
00444 
00445         dlaebz_(&c__3, &itmax, n, &c__2, &c__2, &nb, &atoli, &rtoli, &pivmin, 
00446                 &d__[1], &e[1], &work[1], &iwork[5], &work[*n + 1], &work[*n 
00447                 + 5], &iout, &iwork[1], &w[1], &iblock[1], &iinfo);
00448 
00449         if (iwork[6] == *iu) {
00450             wl = work[*n + 1];
00451             wlu = work[*n + 3];
00452             nwl = iwork[1];
00453             wu = work[*n + 4];
00454             wul = work[*n + 2];
00455             nwu = iwork[4];
00456         } else {
00457             wl = work[*n + 2];
00458             wlu = work[*n + 4];
00459             nwl = iwork[2];
00460             wu = work[*n + 3];
00461             wul = work[*n + 1];
00462             nwu = iwork[3];
00463         }
00464 
00465         if (nwl < 0 || nwl >= *n || nwu < 1 || nwu > *n) {
00466             *info = 4;
00467             return 0;
00468         }
00469     } else {
00470 
00471 /*        RANGE='A' or 'V' -- Set ATOLI */
00472 
00473 /* Computing MAX */
00474         d__3 = abs(d__[1]) + abs(e[1]), d__4 = (d__1 = d__[*n], abs(d__1)) + (
00475                 d__2 = e[*n - 1], abs(d__2));
00476         tnorm = max(d__3,d__4);
00477 
00478         i__1 = *n - 1;
00479         for (j = 2; j <= i__1; ++j) {
00480 /* Computing MAX */
00481             d__4 = tnorm, d__5 = (d__1 = d__[j], abs(d__1)) + (d__2 = e[j - 1]
00482                     , abs(d__2)) + (d__3 = e[j], abs(d__3));
00483             tnorm = max(d__4,d__5);
00484 /* L30: */
00485         }
00486 
00487         if (*abstol <= 0.) {
00488             atoli = ulp * tnorm;
00489         } else {
00490             atoli = *abstol;
00491         }
00492 
00493         if (irange == 2) {
00494             wl = *vl;
00495             wu = *vu;
00496         } else {
00497             wl = 0.;
00498             wu = 0.;
00499         }
00500     }
00501 
00502 /*     Find Eigenvalues -- Loop Over Blocks and recompute NWL and NWU. */
00503 /*     NWL accumulates the number of eigenvalues .le. WL, */
00504 /*     NWU accumulates the number of eigenvalues .le. WU */
00505 
00506     *m = 0;
00507     iend = 0;
00508     *info = 0;
00509     nwl = 0;
00510     nwu = 0;
00511 
00512     i__1 = *nsplit;
00513     for (jb = 1; jb <= i__1; ++jb) {
00514         ioff = iend;
00515         ibegin = ioff + 1;
00516         iend = isplit[jb];
00517         in = iend - ioff;
00518 
00519         if (in == 1) {
00520 
00521 /*           Special Case -- IN=1 */
00522 
00523             if (irange == 1 || wl >= d__[ibegin] - pivmin) {
00524                 ++nwl;
00525             }
00526             if (irange == 1 || wu >= d__[ibegin] - pivmin) {
00527                 ++nwu;
00528             }
00529             if (irange == 1 || wl < d__[ibegin] - pivmin && wu >= d__[ibegin] 
00530                     - pivmin) {
00531                 ++(*m);
00532                 w[*m] = d__[ibegin];
00533                 iblock[*m] = jb;
00534             }
00535         } else {
00536 
00537 /*           General Case -- IN > 1 */
00538 
00539 /*           Compute Gershgorin Interval */
00540 /*           and use it as the initial interval */
00541 
00542             gu = d__[ibegin];
00543             gl = d__[ibegin];
00544             tmp1 = 0.;
00545 
00546             i__2 = iend - 1;
00547             for (j = ibegin; j <= i__2; ++j) {
00548                 tmp2 = (d__1 = e[j], abs(d__1));
00549 /* Computing MAX */
00550                 d__1 = gu, d__2 = d__[j] + tmp1 + tmp2;
00551                 gu = max(d__1,d__2);
00552 /* Computing MIN */
00553                 d__1 = gl, d__2 = d__[j] - tmp1 - tmp2;
00554                 gl = min(d__1,d__2);
00555                 tmp1 = tmp2;
00556 /* L40: */
00557             }
00558 
00559 /* Computing MAX */
00560             d__1 = gu, d__2 = d__[iend] + tmp1;
00561             gu = max(d__1,d__2);
00562 /* Computing MIN */
00563             d__1 = gl, d__2 = d__[iend] - tmp1;
00564             gl = min(d__1,d__2);
00565 /* Computing MAX */
00566             d__1 = abs(gl), d__2 = abs(gu);
00567             bnorm = max(d__1,d__2);
00568             gl = gl - bnorm * 2.1 * ulp * in - pivmin * 2.1;
00569             gu = gu + bnorm * 2.1 * ulp * in + pivmin * 2.1;
00570 
00571 /*           Compute ATOLI for the current submatrix */
00572 
00573             if (*abstol <= 0.) {
00574 /* Computing MAX */
00575                 d__1 = abs(gl), d__2 = abs(gu);
00576                 atoli = ulp * max(d__1,d__2);
00577             } else {
00578                 atoli = *abstol;
00579             }
00580 
00581             if (irange > 1) {
00582                 if (gu < wl) {
00583                     nwl += in;
00584                     nwu += in;
00585                     goto L70;
00586                 }
00587                 gl = max(gl,wl);
00588                 gu = min(gu,wu);
00589                 if (gl >= gu) {
00590                     goto L70;
00591                 }
00592             }
00593 
00594 /*           Set Up Initial Interval */
00595 
00596             work[*n + 1] = gl;
00597             work[*n + in + 1] = gu;
00598             dlaebz_(&c__1, &c__0, &in, &in, &c__1, &nb, &atoli, &rtoli, &
00599                     pivmin, &d__[ibegin], &e[ibegin], &work[ibegin], idumma, &
00600                     work[*n + 1], &work[*n + (in << 1) + 1], &im, &iwork[1], &
00601                     w[*m + 1], &iblock[*m + 1], &iinfo);
00602 
00603             nwl += iwork[1];
00604             nwu += iwork[in + 1];
00605             iwoff = *m - iwork[1];
00606 
00607 /*           Compute Eigenvalues */
00608 
00609             itmax = (integer) ((log(gu - gl + pivmin) - log(pivmin)) / log(2.)
00610                     ) + 2;
00611             dlaebz_(&c__2, &itmax, &in, &in, &c__1, &nb, &atoli, &rtoli, &
00612                     pivmin, &d__[ibegin], &e[ibegin], &work[ibegin], idumma, &
00613                     work[*n + 1], &work[*n + (in << 1) + 1], &iout, &iwork[1], 
00614                      &w[*m + 1], &iblock[*m + 1], &iinfo);
00615 
00616 /*           Copy Eigenvalues Into W and IBLOCK */
00617 /*           Use -JB for block number for unconverged eigenvalues. */
00618 
00619             i__2 = iout;
00620             for (j = 1; j <= i__2; ++j) {
00621                 tmp1 = (work[j + *n] + work[j + in + *n]) * .5;
00622 
00623 /*              Flag non-convergence. */
00624 
00625                 if (j > iout - iinfo) {
00626                     ncnvrg = TRUE_;
00627                     ib = -jb;
00628                 } else {
00629                     ib = jb;
00630                 }
00631                 i__3 = iwork[j + in] + iwoff;
00632                 for (je = iwork[j] + 1 + iwoff; je <= i__3; ++je) {
00633                     w[je] = tmp1;
00634                     iblock[je] = ib;
00635 /* L50: */
00636                 }
00637 /* L60: */
00638             }
00639 
00640             *m += im;
00641         }
00642 L70:
00643         ;
00644     }
00645 
00646 /*     If RANGE='I', then (WL,WU) contains eigenvalues NWL+1,...,NWU */
00647 /*     If NWL+1 < IL or NWU > IU, discard extra eigenvalues. */
00648 
00649     if (irange == 3) {
00650         im = 0;
00651         idiscl = *il - 1 - nwl;
00652         idiscu = nwu - *iu;
00653 
00654         if (idiscl > 0 || idiscu > 0) {
00655             i__1 = *m;
00656             for (je = 1; je <= i__1; ++je) {
00657                 if (w[je] <= wlu && idiscl > 0) {
00658                     --idiscl;
00659                 } else if (w[je] >= wul && idiscu > 0) {
00660                     --idiscu;
00661                 } else {
00662                     ++im;
00663                     w[im] = w[je];
00664                     iblock[im] = iblock[je];
00665                 }
00666 /* L80: */
00667             }
00668             *m = im;
00669         }
00670         if (idiscl > 0 || idiscu > 0) {
00671 
00672 /*           Code to deal with effects of bad arithmetic: */
00673 /*           Some low eigenvalues to be discarded are not in (WL,WLU], */
00674 /*           or high eigenvalues to be discarded are not in (WUL,WU] */
00675 /*           so just kill off the smallest IDISCL/largest IDISCU */
00676 /*           eigenvalues, by simply finding the smallest/largest */
00677 /*           eigenvalue(s). */
00678 
00679 /*           (If N(w) is monotone non-decreasing, this should never */
00680 /*               happen.) */
00681 
00682             if (idiscl > 0) {
00683                 wkill = wu;
00684                 i__1 = idiscl;
00685                 for (jdisc = 1; jdisc <= i__1; ++jdisc) {
00686                     iw = 0;
00687                     i__2 = *m;
00688                     for (je = 1; je <= i__2; ++je) {
00689                         if (iblock[je] != 0 && (w[je] < wkill || iw == 0)) {
00690                             iw = je;
00691                             wkill = w[je];
00692                         }
00693 /* L90: */
00694                     }
00695                     iblock[iw] = 0;
00696 /* L100: */
00697                 }
00698             }
00699             if (idiscu > 0) {
00700 
00701                 wkill = wl;
00702                 i__1 = idiscu;
00703                 for (jdisc = 1; jdisc <= i__1; ++jdisc) {
00704                     iw = 0;
00705                     i__2 = *m;
00706                     for (je = 1; je <= i__2; ++je) {
00707                         if (iblock[je] != 0 && (w[je] > wkill || iw == 0)) {
00708                             iw = je;
00709                             wkill = w[je];
00710                         }
00711 /* L110: */
00712                     }
00713                     iblock[iw] = 0;
00714 /* L120: */
00715                 }
00716             }
00717             im = 0;
00718             i__1 = *m;
00719             for (je = 1; je <= i__1; ++je) {
00720                 if (iblock[je] != 0) {
00721                     ++im;
00722                     w[im] = w[je];
00723                     iblock[im] = iblock[je];
00724                 }
00725 /* L130: */
00726             }
00727             *m = im;
00728         }
00729         if (idiscl < 0 || idiscu < 0) {
00730             toofew = TRUE_;
00731         }
00732     }
00733 
00734 /*     If ORDER='B', do nothing -- the eigenvalues are already sorted */
00735 /*        by block. */
00736 /*     If ORDER='E', sort the eigenvalues from smallest to largest */
00737 
00738     if (iorder == 1 && *nsplit > 1) {
00739         i__1 = *m - 1;
00740         for (je = 1; je <= i__1; ++je) {
00741             ie = 0;
00742             tmp1 = w[je];
00743             i__2 = *m;
00744             for (j = je + 1; j <= i__2; ++j) {
00745                 if (w[j] < tmp1) {
00746                     ie = j;
00747                     tmp1 = w[j];
00748                 }
00749 /* L140: */
00750             }
00751 
00752             if (ie != 0) {
00753                 itmp1 = iblock[ie];
00754                 w[ie] = w[je];
00755                 iblock[ie] = iblock[je];
00756                 w[je] = tmp1;
00757                 iblock[je] = itmp1;
00758             }
00759 /* L150: */
00760         }
00761     }
00762 
00763     *info = 0;
00764     if (ncnvrg) {
00765         ++(*info);
00766     }
00767     if (toofew) {
00768         *info += 2;
00769     }
00770     return 0;
00771 
00772 /*     End of DSTEBZ */
00773 
00774 } /* dstebz_ */


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:55:49