123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775 |
- /* dstebz.f -- translated by f2c (version 20061008).
- You must link the resulting object file with libf2c:
- on Microsoft Windows system, link with libf2c.lib;
- on Linux or Unix systems, link with .../path/to/libf2c.a -lm
- or, if you install libf2c.a in a standard place, with -lf2c -lm
- -- in that order, at the end of the command line, as in
- cc *.o -lf2c -lm
- Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
- http://www.netlib.org/f2c/libf2c.zip
- */
- #include "f2c.h"
- #include "blaswrap.h"
- /* Table of constant values */
- static integer c__1 = 1;
- static integer c_n1 = -1;
- static integer c__3 = 3;
- static integer c__2 = 2;
- static integer c__0 = 0;
- /* Subroutine */ int _starpu_dstebz_(char *range, char *order, integer *n, doublereal
- *vl, doublereal *vu, integer *il, integer *iu, doublereal *abstol,
- doublereal *d__, doublereal *e, integer *m, integer *nsplit,
- doublereal *w, integer *iblock, integer *isplit, doublereal *work,
- integer *iwork, integer *info)
- {
- /* System generated locals */
- integer i__1, i__2, i__3;
- doublereal d__1, d__2, d__3, d__4, d__5;
- /* Builtin functions */
- double sqrt(doublereal), log(doublereal);
- /* Local variables */
- integer j, ib, jb, ie, je, nb;
- doublereal gl;
- integer im, in;
- doublereal gu;
- integer iw;
- doublereal wl, wu;
- integer nwl;
- doublereal ulp, wlu, wul;
- integer nwu;
- doublereal tmp1, tmp2;
- integer iend, ioff, iout, itmp1, jdisc;
- extern logical _starpu_lsame_(char *, char *);
- integer iinfo;
- doublereal atoli;
- integer iwoff;
- doublereal bnorm;
- integer itmax;
- doublereal wkill, rtoli, tnorm;
- extern doublereal _starpu_dlamch_(char *);
- integer ibegin;
- extern /* Subroutine */ int _starpu_dlaebz_(integer *, integer *, integer *,
- integer *, integer *, integer *, doublereal *, doublereal *,
- doublereal *, doublereal *, doublereal *, doublereal *, integer *,
- doublereal *, doublereal *, integer *, integer *, doublereal *,
- integer *, integer *);
- integer irange, idiscl;
- doublereal safemn;
- integer idumma[1];
- extern /* Subroutine */ int _starpu_xerbla_(char *, integer *);
- extern integer _starpu_ilaenv_(integer *, char *, char *, integer *, integer *,
- integer *, integer *);
- integer idiscu, iorder;
- logical ncnvrg;
- doublereal pivmin;
- logical toofew;
- /* -- LAPACK routine (version 3.2) -- */
- /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
- /* November 2006 */
- /* 8-18-00: Increase FUDGE factor for T3E (eca) */
- /* .. Scalar Arguments .. */
- /* .. */
- /* .. Array Arguments .. */
- /* .. */
- /* Purpose */
- /* ======= */
- /* DSTEBZ computes the eigenvalues of a symmetric tridiagonal */
- /* matrix T. The user may ask for all eigenvalues, all eigenvalues */
- /* in the half-open interval (VL, VU], or the IL-th through IU-th */
- /* eigenvalues. */
- /* To avoid overflow, the matrix must be scaled so that its */
- /* largest element is no greater than overflow**(1/2) * */
- /* underflow**(1/4) in absolute value, and for greatest */
- /* accuracy, it should not be much smaller than that. */
- /* See W. Kahan "Accurate Eigenvalues of a Symmetric Tridiagonal */
- /* Matrix", Report CS41, Computer Science Dept., Stanford */
- /* University, July 21, 1966. */
- /* Arguments */
- /* ========= */
- /* RANGE (input) CHARACTER*1 */
- /* = 'A': ("All") all eigenvalues will be found. */
- /* = 'V': ("Value") all eigenvalues in the half-open interval */
- /* (VL, VU] will be found. */
- /* = 'I': ("Index") the IL-th through IU-th eigenvalues (of the */
- /* entire matrix) will be found. */
- /* ORDER (input) CHARACTER*1 */
- /* = 'B': ("By Block") the eigenvalues will be grouped by */
- /* split-off block (see IBLOCK, ISPLIT) and */
- /* ordered from smallest to largest within */
- /* the block. */
- /* = 'E': ("Entire matrix") */
- /* the eigenvalues for the entire matrix */
- /* will be ordered from smallest to */
- /* largest. */
- /* N (input) INTEGER */
- /* The order of the tridiagonal matrix T. N >= 0. */
- /* VL (input) DOUBLE PRECISION */
- /* VU (input) DOUBLE PRECISION */
- /* If RANGE='V', the lower and upper bounds of the interval to */
- /* be searched for eigenvalues. Eigenvalues less than or equal */
- /* to VL, or greater than VU, will not be returned. VL < VU. */
- /* Not referenced if RANGE = 'A' or 'I'. */
- /* IL (input) INTEGER */
- /* IU (input) INTEGER */
- /* If RANGE='I', the indices (in ascending order) of the */
- /* smallest and largest eigenvalues to be returned. */
- /* 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0. */
- /* Not referenced if RANGE = 'A' or 'V'. */
- /* ABSTOL (input) DOUBLE PRECISION */
- /* The absolute tolerance for the eigenvalues. An eigenvalue */
- /* (or cluster) is considered to be located if it has been */
- /* determined to lie in an interval whose width is ABSTOL or */
- /* less. If ABSTOL is less than or equal to zero, then ULP*|T| */
- /* will be used, where |T| means the 1-norm of T. */
- /* Eigenvalues will be computed most accurately when ABSTOL is */
- /* set to twice the underflow threshold 2*DLAMCH('S'), not zero. */
- /* D (input) DOUBLE PRECISION array, dimension (N) */
- /* The n diagonal elements of the tridiagonal matrix T. */
- /* E (input) DOUBLE PRECISION array, dimension (N-1) */
- /* The (n-1) off-diagonal elements of the tridiagonal matrix T. */
- /* M (output) INTEGER */
- /* The actual number of eigenvalues found. 0 <= M <= N. */
- /* (See also the description of INFO=2,3.) */
- /* NSPLIT (output) INTEGER */
- /* The number of diagonal blocks in the matrix T. */
- /* 1 <= NSPLIT <= N. */
- /* W (output) DOUBLE PRECISION array, dimension (N) */
- /* On exit, the first M elements of W will contain the */
- /* eigenvalues. (DSTEBZ may use the remaining N-M elements as */
- /* workspace.) */
- /* IBLOCK (output) INTEGER array, dimension (N) */
- /* At each row/column j where E(j) is zero or small, the */
- /* matrix T is considered to split into a block diagonal */
- /* matrix. On exit, if INFO = 0, IBLOCK(i) specifies to which */
- /* block (from 1 to the number of blocks) the eigenvalue W(i) */
- /* belongs. (DSTEBZ may use the remaining N-M elements as */
- /* workspace.) */
- /* ISPLIT (output) INTEGER array, dimension (N) */
- /* The splitting points, at which T breaks up into submatrices. */
- /* The first submatrix consists of rows/columns 1 to ISPLIT(1), */
- /* the second of rows/columns ISPLIT(1)+1 through ISPLIT(2), */
- /* etc., and the NSPLIT-th consists of rows/columns */
- /* ISPLIT(NSPLIT-1)+1 through ISPLIT(NSPLIT)=N. */
- /* (Only the first NSPLIT elements will actually be used, but */
- /* since the user cannot know a priori what value NSPLIT will */
- /* have, N words must be reserved for ISPLIT.) */
- /* WORK (workspace) DOUBLE PRECISION array, dimension (4*N) */
- /* IWORK (workspace) INTEGER array, dimension (3*N) */
- /* INFO (output) INTEGER */
- /* = 0: successful exit */
- /* < 0: if INFO = -i, the i-th argument had an illegal value */
- /* > 0: some or all of the eigenvalues failed to converge or */
- /* were not computed: */
- /* =1 or 3: Bisection failed to converge for some */
- /* eigenvalues; these eigenvalues are flagged by a */
- /* negative block number. The effect is that the */
- /* eigenvalues may not be as accurate as the */
- /* absolute and relative tolerances. This is */
- /* generally caused by unexpectedly inaccurate */
- /* arithmetic. */
- /* =2 or 3: RANGE='I' only: Not all of the eigenvalues */
- /* IL:IU were found. */
- /* Effect: M < IU+1-IL */
- /* Cause: non-monotonic arithmetic, causing the */
- /* Sturm sequence to be non-monotonic. */
- /* Cure: recalculate, using RANGE='A', and pick */
- /* out eigenvalues IL:IU. In some cases, */
- /* increasing the PARAMETER "FUDGE" may */
- /* make things work. */
- /* = 4: RANGE='I', and the Gershgorin interval */
- /* initially used was too small. No eigenvalues */
- /* were computed. */
- /* Probable cause: your machine has sloppy */
- /* floating-point arithmetic. */
- /* Cure: Increase the PARAMETER "FUDGE", */
- /* recompile, and try again. */
- /* Internal Parameters */
- /* =================== */
- /* RELFAC DOUBLE PRECISION, default = 2.0e0 */
- /* The relative tolerance. An interval (a,b] lies within */
- /* "relative tolerance" if b-a < RELFAC*ulp*max(|a|,|b|), */
- /* where "ulp" is the machine precision (distance from 1 to */
- /* the next larger floating point number.) */
- /* FUDGE DOUBLE PRECISION, default = 2 */
- /* A "fudge factor" to widen the Gershgorin intervals. Ideally, */
- /* a value of 1 should work, but on machines with sloppy */
- /* arithmetic, this needs to be larger. The default for */
- /* publicly released versions should be large enough to handle */
- /* the worst machine around. Note that this has no effect */
- /* on accuracy of the solution. */
- /* ===================================================================== */
- /* .. Parameters .. */
- /* .. */
- /* .. Local Scalars .. */
- /* .. */
- /* .. Local Arrays .. */
- /* .. */
- /* .. External Functions .. */
- /* .. */
- /* .. External Subroutines .. */
- /* .. */
- /* .. Intrinsic Functions .. */
- /* .. */
- /* .. Executable Statements .. */
- /* Parameter adjustments */
- --iwork;
- --work;
- --isplit;
- --iblock;
- --w;
- --e;
- --d__;
- /* Function Body */
- *info = 0;
- /* Decode RANGE */
- if (_starpu_lsame_(range, "A")) {
- irange = 1;
- } else if (_starpu_lsame_(range, "V")) {
- irange = 2;
- } else if (_starpu_lsame_(range, "I")) {
- irange = 3;
- } else {
- irange = 0;
- }
- /* Decode ORDER */
- if (_starpu_lsame_(order, "B")) {
- iorder = 2;
- } else if (_starpu_lsame_(order, "E")) {
- iorder = 1;
- } else {
- iorder = 0;
- }
- /* Check for Errors */
- if (irange <= 0) {
- *info = -1;
- } else if (iorder <= 0) {
- *info = -2;
- } else if (*n < 0) {
- *info = -3;
- } else if (irange == 2) {
- if (*vl >= *vu) {
- *info = -5;
- }
- } else if (irange == 3 && (*il < 1 || *il > max(1,*n))) {
- *info = -6;
- } else if (irange == 3 && (*iu < min(*n,*il) || *iu > *n)) {
- *info = -7;
- }
- if (*info != 0) {
- i__1 = -(*info);
- _starpu_xerbla_("DSTEBZ", &i__1);
- return 0;
- }
- /* Initialize error flags */
- *info = 0;
- ncnvrg = FALSE_;
- toofew = FALSE_;
- /* Quick return if possible */
- *m = 0;
- if (*n == 0) {
- return 0;
- }
- /* Simplifications: */
- if (irange == 3 && *il == 1 && *iu == *n) {
- irange = 1;
- }
- /* Get machine constants */
- /* NB is the minimum vector length for vector bisection, or 0 */
- /* if only scalar is to be done. */
- safemn = _starpu_dlamch_("S");
- ulp = _starpu_dlamch_("P");
- rtoli = ulp * 2.;
- nb = _starpu_ilaenv_(&c__1, "DSTEBZ", " ", n, &c_n1, &c_n1, &c_n1);
- if (nb <= 1) {
- nb = 0;
- }
- /* Special Case when N=1 */
- if (*n == 1) {
- *nsplit = 1;
- isplit[1] = 1;
- if (irange == 2 && (*vl >= d__[1] || *vu < d__[1])) {
- *m = 0;
- } else {
- w[1] = d__[1];
- iblock[1] = 1;
- *m = 1;
- }
- return 0;
- }
- /* Compute Splitting Points */
- *nsplit = 1;
- work[*n] = 0.;
- pivmin = 1.;
- /* DIR$ NOVECTOR */
- i__1 = *n;
- for (j = 2; j <= i__1; ++j) {
- /* Computing 2nd power */
- d__1 = e[j - 1];
- tmp1 = d__1 * d__1;
- /* Computing 2nd power */
- d__2 = ulp;
- if ((d__1 = d__[j] * d__[j - 1], abs(d__1)) * (d__2 * d__2) + safemn
- > tmp1) {
- isplit[*nsplit] = j - 1;
- ++(*nsplit);
- work[j - 1] = 0.;
- } else {
- work[j - 1] = tmp1;
- pivmin = max(pivmin,tmp1);
- }
- /* L10: */
- }
- isplit[*nsplit] = *n;
- pivmin *= safemn;
- /* Compute Interval and ATOLI */
- if (irange == 3) {
- /* RANGE='I': Compute the interval containing eigenvalues */
- /* IL through IU. */
- /* Compute Gershgorin interval for entire (split) matrix */
- /* and use it as the initial interval */
- gu = d__[1];
- gl = d__[1];
- tmp1 = 0.;
- i__1 = *n - 1;
- for (j = 1; j <= i__1; ++j) {
- tmp2 = sqrt(work[j]);
- /* Computing MAX */
- d__1 = gu, d__2 = d__[j] + tmp1 + tmp2;
- gu = max(d__1,d__2);
- /* Computing MIN */
- d__1 = gl, d__2 = d__[j] - tmp1 - tmp2;
- gl = min(d__1,d__2);
- tmp1 = tmp2;
- /* L20: */
- }
- /* Computing MAX */
- d__1 = gu, d__2 = d__[*n] + tmp1;
- gu = max(d__1,d__2);
- /* Computing MIN */
- d__1 = gl, d__2 = d__[*n] - tmp1;
- gl = min(d__1,d__2);
- /* Computing MAX */
- d__1 = abs(gl), d__2 = abs(gu);
- tnorm = max(d__1,d__2);
- gl = gl - tnorm * 2.1 * ulp * *n - pivmin * 4.2000000000000002;
- gu = gu + tnorm * 2.1 * ulp * *n + pivmin * 2.1;
- /* Compute Iteration parameters */
- itmax = (integer) ((log(tnorm + pivmin) - log(pivmin)) / log(2.)) + 2;
- if (*abstol <= 0.) {
- atoli = ulp * tnorm;
- } else {
- atoli = *abstol;
- }
- work[*n + 1] = gl;
- work[*n + 2] = gl;
- work[*n + 3] = gu;
- work[*n + 4] = gu;
- work[*n + 5] = gl;
- work[*n + 6] = gu;
- iwork[1] = -1;
- iwork[2] = -1;
- iwork[3] = *n + 1;
- iwork[4] = *n + 1;
- iwork[5] = *il - 1;
- iwork[6] = *iu;
- _starpu_dlaebz_(&c__3, &itmax, n, &c__2, &c__2, &nb, &atoli, &rtoli, &pivmin,
- &d__[1], &e[1], &work[1], &iwork[5], &work[*n + 1], &work[*n
- + 5], &iout, &iwork[1], &w[1], &iblock[1], &iinfo);
- if (iwork[6] == *iu) {
- wl = work[*n + 1];
- wlu = work[*n + 3];
- nwl = iwork[1];
- wu = work[*n + 4];
- wul = work[*n + 2];
- nwu = iwork[4];
- } else {
- wl = work[*n + 2];
- wlu = work[*n + 4];
- nwl = iwork[2];
- wu = work[*n + 3];
- wul = work[*n + 1];
- nwu = iwork[3];
- }
- if (nwl < 0 || nwl >= *n || nwu < 1 || nwu > *n) {
- *info = 4;
- return 0;
- }
- } else {
- /* RANGE='A' or 'V' -- Set ATOLI */
- /* Computing MAX */
- d__3 = abs(d__[1]) + abs(e[1]), d__4 = (d__1 = d__[*n], abs(d__1)) + (
- d__2 = e[*n - 1], abs(d__2));
- tnorm = max(d__3,d__4);
- i__1 = *n - 1;
- for (j = 2; j <= i__1; ++j) {
- /* Computing MAX */
- d__4 = tnorm, d__5 = (d__1 = d__[j], abs(d__1)) + (d__2 = e[j - 1]
- , abs(d__2)) + (d__3 = e[j], abs(d__3));
- tnorm = max(d__4,d__5);
- /* L30: */
- }
- if (*abstol <= 0.) {
- atoli = ulp * tnorm;
- } else {
- atoli = *abstol;
- }
- if (irange == 2) {
- wl = *vl;
- wu = *vu;
- } else {
- wl = 0.;
- wu = 0.;
- }
- }
- /* Find Eigenvalues -- Loop Over Blocks and recompute NWL and NWU. */
- /* NWL accumulates the number of eigenvalues .le. WL, */
- /* NWU accumulates the number of eigenvalues .le. WU */
- *m = 0;
- iend = 0;
- *info = 0;
- nwl = 0;
- nwu = 0;
- i__1 = *nsplit;
- for (jb = 1; jb <= i__1; ++jb) {
- ioff = iend;
- ibegin = ioff + 1;
- iend = isplit[jb];
- in = iend - ioff;
- if (in == 1) {
- /* Special Case -- IN=1 */
- if (irange == 1 || wl >= d__[ibegin] - pivmin) {
- ++nwl;
- }
- if (irange == 1 || wu >= d__[ibegin] - pivmin) {
- ++nwu;
- }
- if (irange == 1 || wl < d__[ibegin] - pivmin && wu >= d__[ibegin]
- - pivmin) {
- ++(*m);
- w[*m] = d__[ibegin];
- iblock[*m] = jb;
- }
- } else {
- /* General Case -- IN > 1 */
- /* Compute Gershgorin Interval */
- /* and use it as the initial interval */
- gu = d__[ibegin];
- gl = d__[ibegin];
- tmp1 = 0.;
- i__2 = iend - 1;
- for (j = ibegin; j <= i__2; ++j) {
- tmp2 = (d__1 = e[j], abs(d__1));
- /* Computing MAX */
- d__1 = gu, d__2 = d__[j] + tmp1 + tmp2;
- gu = max(d__1,d__2);
- /* Computing MIN */
- d__1 = gl, d__2 = d__[j] - tmp1 - tmp2;
- gl = min(d__1,d__2);
- tmp1 = tmp2;
- /* L40: */
- }
- /* Computing MAX */
- d__1 = gu, d__2 = d__[iend] + tmp1;
- gu = max(d__1,d__2);
- /* Computing MIN */
- d__1 = gl, d__2 = d__[iend] - tmp1;
- gl = min(d__1,d__2);
- /* Computing MAX */
- d__1 = abs(gl), d__2 = abs(gu);
- bnorm = max(d__1,d__2);
- gl = gl - bnorm * 2.1 * ulp * in - pivmin * 2.1;
- gu = gu + bnorm * 2.1 * ulp * in + pivmin * 2.1;
- /* Compute ATOLI for the current submatrix */
- if (*abstol <= 0.) {
- /* Computing MAX */
- d__1 = abs(gl), d__2 = abs(gu);
- atoli = ulp * max(d__1,d__2);
- } else {
- atoli = *abstol;
- }
- if (irange > 1) {
- if (gu < wl) {
- nwl += in;
- nwu += in;
- goto L70;
- }
- gl = max(gl,wl);
- gu = min(gu,wu);
- if (gl >= gu) {
- goto L70;
- }
- }
- /* Set Up Initial Interval */
- work[*n + 1] = gl;
- work[*n + in + 1] = gu;
- _starpu_dlaebz_(&c__1, &c__0, &in, &in, &c__1, &nb, &atoli, &rtoli, &
- pivmin, &d__[ibegin], &e[ibegin], &work[ibegin], idumma, &
- work[*n + 1], &work[*n + (in << 1) + 1], &im, &iwork[1], &
- w[*m + 1], &iblock[*m + 1], &iinfo);
- nwl += iwork[1];
- nwu += iwork[in + 1];
- iwoff = *m - iwork[1];
- /* Compute Eigenvalues */
- itmax = (integer) ((log(gu - gl + pivmin) - log(pivmin)) / log(2.)
- ) + 2;
- _starpu_dlaebz_(&c__2, &itmax, &in, &in, &c__1, &nb, &atoli, &rtoli, &
- pivmin, &d__[ibegin], &e[ibegin], &work[ibegin], idumma, &
- work[*n + 1], &work[*n + (in << 1) + 1], &iout, &iwork[1],
- &w[*m + 1], &iblock[*m + 1], &iinfo);
- /* Copy Eigenvalues Into W and IBLOCK */
- /* Use -JB for block number for unconverged eigenvalues. */
- i__2 = iout;
- for (j = 1; j <= i__2; ++j) {
- tmp1 = (work[j + *n] + work[j + in + *n]) * .5;
- /* Flag non-convergence. */
- if (j > iout - iinfo) {
- ncnvrg = TRUE_;
- ib = -jb;
- } else {
- ib = jb;
- }
- i__3 = iwork[j + in] + iwoff;
- for (je = iwork[j] + 1 + iwoff; je <= i__3; ++je) {
- w[je] = tmp1;
- iblock[je] = ib;
- /* L50: */
- }
- /* L60: */
- }
- *m += im;
- }
- L70:
- ;
- }
- /* If RANGE='I', then (WL,WU) contains eigenvalues NWL+1,...,NWU */
- /* If NWL+1 < IL or NWU > IU, discard extra eigenvalues. */
- if (irange == 3) {
- im = 0;
- idiscl = *il - 1 - nwl;
- idiscu = nwu - *iu;
- if (idiscl > 0 || idiscu > 0) {
- i__1 = *m;
- for (je = 1; je <= i__1; ++je) {
- if (w[je] <= wlu && idiscl > 0) {
- --idiscl;
- } else if (w[je] >= wul && idiscu > 0) {
- --idiscu;
- } else {
- ++im;
- w[im] = w[je];
- iblock[im] = iblock[je];
- }
- /* L80: */
- }
- *m = im;
- }
- if (idiscl > 0 || idiscu > 0) {
- /* Code to deal with effects of bad arithmetic: */
- /* Some low eigenvalues to be discarded are not in (WL,WLU], */
- /* or high eigenvalues to be discarded are not in (WUL,WU] */
- /* so just kill off the smallest IDISCL/largest IDISCU */
- /* eigenvalues, by simply finding the smallest/largest */
- /* eigenvalue(s). */
- /* (If N(w) is monotone non-decreasing, this should never */
- /* happen.) */
- if (idiscl > 0) {
- wkill = wu;
- i__1 = idiscl;
- for (jdisc = 1; jdisc <= i__1; ++jdisc) {
- iw = 0;
- i__2 = *m;
- for (je = 1; je <= i__2; ++je) {
- if (iblock[je] != 0 && (w[je] < wkill || iw == 0)) {
- iw = je;
- wkill = w[je];
- }
- /* L90: */
- }
- iblock[iw] = 0;
- /* L100: */
- }
- }
- if (idiscu > 0) {
- wkill = wl;
- i__1 = idiscu;
- for (jdisc = 1; jdisc <= i__1; ++jdisc) {
- iw = 0;
- i__2 = *m;
- for (je = 1; je <= i__2; ++je) {
- if (iblock[je] != 0 && (w[je] > wkill || iw == 0)) {
- iw = je;
- wkill = w[je];
- }
- /* L110: */
- }
- iblock[iw] = 0;
- /* L120: */
- }
- }
- im = 0;
- i__1 = *m;
- for (je = 1; je <= i__1; ++je) {
- if (iblock[je] != 0) {
- ++im;
- w[im] = w[je];
- iblock[im] = iblock[je];
- }
- /* L130: */
- }
- *m = im;
- }
- if (idiscl < 0 || idiscu < 0) {
- toofew = TRUE_;
- }
- }
- /* If ORDER='B', do nothing -- the eigenvalues are already sorted */
- /* by block. */
- /* If ORDER='E', sort the eigenvalues from smallest to largest */
- if (iorder == 1 && *nsplit > 1) {
- i__1 = *m - 1;
- for (je = 1; je <= i__1; ++je) {
- ie = 0;
- tmp1 = w[je];
- i__2 = *m;
- for (j = je + 1; j <= i__2; ++j) {
- if (w[j] < tmp1) {
- ie = j;
- tmp1 = w[j];
- }
- /* L140: */
- }
- if (ie != 0) {
- itmp1 = iblock[ie];
- w[ie] = w[je];
- iblock[ie] = iblock[je];
- w[je] = tmp1;
- iblock[je] = itmp1;
- }
- /* L150: */
- }
- }
- *info = 0;
- if (ncnvrg) {
- ++(*info);
- }
- if (toofew) {
- *info += 2;
- }
- return 0;
- /* End of DSTEBZ */
- } /* _starpu_dstebz_ */
|