dstebz.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775
  1. /* dstebz.f -- translated by f2c (version 20061008).
  2. You must link the resulting object file with libf2c:
  3. on Microsoft Windows system, link with libf2c.lib;
  4. on Linux or Unix systems, link with .../path/to/libf2c.a -lm
  5. or, if you install libf2c.a in a standard place, with -lf2c -lm
  6. -- in that order, at the end of the command line, as in
  7. cc *.o -lf2c -lm
  8. Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
  9. http://www.netlib.org/f2c/libf2c.zip
  10. */
  11. #include "f2c.h"
  12. #include "blaswrap.h"
  13. /* Table of constant values */
  14. static integer c__1 = 1;
  15. static integer c_n1 = -1;
  16. static integer c__3 = 3;
  17. static integer c__2 = 2;
  18. static integer c__0 = 0;
  19. /* Subroutine */ int _starpu_dstebz_(char *range, char *order, integer *n, doublereal
  20. *vl, doublereal *vu, integer *il, integer *iu, doublereal *abstol,
  21. doublereal *d__, doublereal *e, integer *m, integer *nsplit,
  22. doublereal *w, integer *iblock, integer *isplit, doublereal *work,
  23. integer *iwork, integer *info)
  24. {
  25. /* System generated locals */
  26. integer i__1, i__2, i__3;
  27. doublereal d__1, d__2, d__3, d__4, d__5;
  28. /* Builtin functions */
  29. double sqrt(doublereal), log(doublereal);
  30. /* Local variables */
  31. integer j, ib, jb, ie, je, nb;
  32. doublereal gl;
  33. integer im, in;
  34. doublereal gu;
  35. integer iw;
  36. doublereal wl, wu;
  37. integer nwl;
  38. doublereal ulp, wlu, wul;
  39. integer nwu;
  40. doublereal tmp1, tmp2;
  41. integer iend, ioff, iout, itmp1, jdisc;
  42. extern logical _starpu_lsame_(char *, char *);
  43. integer iinfo;
  44. doublereal atoli;
  45. integer iwoff;
  46. doublereal bnorm;
  47. integer itmax;
  48. doublereal wkill, rtoli, tnorm;
  49. extern doublereal _starpu_dlamch_(char *);
  50. integer ibegin;
  51. extern /* Subroutine */ int _starpu_dlaebz_(integer *, integer *, integer *,
  52. integer *, integer *, integer *, doublereal *, doublereal *,
  53. doublereal *, doublereal *, doublereal *, doublereal *, integer *,
  54. doublereal *, doublereal *, integer *, integer *, doublereal *,
  55. integer *, integer *);
  56. integer irange, idiscl;
  57. doublereal safemn;
  58. integer idumma[1];
  59. extern /* Subroutine */ int _starpu_xerbla_(char *, integer *);
  60. extern integer _starpu_ilaenv_(integer *, char *, char *, integer *, integer *,
  61. integer *, integer *);
  62. integer idiscu, iorder;
  63. logical ncnvrg;
  64. doublereal pivmin;
  65. logical toofew;
  66. /* -- LAPACK routine (version 3.2) -- */
  67. /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
  68. /* November 2006 */
  69. /* 8-18-00: Increase FUDGE factor for T3E (eca) */
  70. /* .. Scalar Arguments .. */
  71. /* .. */
  72. /* .. Array Arguments .. */
  73. /* .. */
  74. /* Purpose */
  75. /* ======= */
  76. /* DSTEBZ computes the eigenvalues of a symmetric tridiagonal */
  77. /* matrix T. The user may ask for all eigenvalues, all eigenvalues */
  78. /* in the half-open interval (VL, VU], or the IL-th through IU-th */
  79. /* eigenvalues. */
  80. /* To avoid overflow, the matrix must be scaled so that its */
  81. /* largest element is no greater than overflow**(1/2) * */
  82. /* underflow**(1/4) in absolute value, and for greatest */
  83. /* accuracy, it should not be much smaller than that. */
  84. /* See W. Kahan "Accurate Eigenvalues of a Symmetric Tridiagonal */
  85. /* Matrix", Report CS41, Computer Science Dept., Stanford */
  86. /* University, July 21, 1966. */
  87. /* Arguments */
  88. /* ========= */
  89. /* RANGE (input) CHARACTER*1 */
  90. /* = 'A': ("All") all eigenvalues will be found. */
  91. /* = 'V': ("Value") all eigenvalues in the half-open interval */
  92. /* (VL, VU] will be found. */
  93. /* = 'I': ("Index") the IL-th through IU-th eigenvalues (of the */
  94. /* entire matrix) will be found. */
  95. /* ORDER (input) CHARACTER*1 */
  96. /* = 'B': ("By Block") the eigenvalues will be grouped by */
  97. /* split-off block (see IBLOCK, ISPLIT) and */
  98. /* ordered from smallest to largest within */
  99. /* the block. */
  100. /* = 'E': ("Entire matrix") */
  101. /* the eigenvalues for the entire matrix */
  102. /* will be ordered from smallest to */
  103. /* largest. */
  104. /* N (input) INTEGER */
  105. /* The order of the tridiagonal matrix T. N >= 0. */
  106. /* VL (input) DOUBLE PRECISION */
  107. /* VU (input) DOUBLE PRECISION */
  108. /* If RANGE='V', the lower and upper bounds of the interval to */
  109. /* be searched for eigenvalues. Eigenvalues less than or equal */
  110. /* to VL, or greater than VU, will not be returned. VL < VU. */
  111. /* Not referenced if RANGE = 'A' or 'I'. */
  112. /* IL (input) INTEGER */
  113. /* IU (input) INTEGER */
  114. /* If RANGE='I', the indices (in ascending order) of the */
  115. /* smallest and largest eigenvalues to be returned. */
  116. /* 1 <= IL <= IU <= N, if N > 0; IL = 1 and IU = 0 if N = 0. */
  117. /* Not referenced if RANGE = 'A' or 'V'. */
  118. /* ABSTOL (input) DOUBLE PRECISION */
  119. /* The absolute tolerance for the eigenvalues. An eigenvalue */
  120. /* (or cluster) is considered to be located if it has been */
  121. /* determined to lie in an interval whose width is ABSTOL or */
  122. /* less. If ABSTOL is less than or equal to zero, then ULP*|T| */
  123. /* will be used, where |T| means the 1-norm of T. */
  124. /* Eigenvalues will be computed most accurately when ABSTOL is */
  125. /* set to twice the underflow threshold 2*DLAMCH('S'), not zero. */
  126. /* D (input) DOUBLE PRECISION array, dimension (N) */
  127. /* The n diagonal elements of the tridiagonal matrix T. */
  128. /* E (input) DOUBLE PRECISION array, dimension (N-1) */
  129. /* The (n-1) off-diagonal elements of the tridiagonal matrix T. */
  130. /* M (output) INTEGER */
  131. /* The actual number of eigenvalues found. 0 <= M <= N. */
  132. /* (See also the description of INFO=2,3.) */
  133. /* NSPLIT (output) INTEGER */
  134. /* The number of diagonal blocks in the matrix T. */
  135. /* 1 <= NSPLIT <= N. */
  136. /* W (output) DOUBLE PRECISION array, dimension (N) */
  137. /* On exit, the first M elements of W will contain the */
  138. /* eigenvalues. (DSTEBZ may use the remaining N-M elements as */
  139. /* workspace.) */
  140. /* IBLOCK (output) INTEGER array, dimension (N) */
  141. /* At each row/column j where E(j) is zero or small, the */
  142. /* matrix T is considered to split into a block diagonal */
  143. /* matrix. On exit, if INFO = 0, IBLOCK(i) specifies to which */
  144. /* block (from 1 to the number of blocks) the eigenvalue W(i) */
  145. /* belongs. (DSTEBZ may use the remaining N-M elements as */
  146. /* workspace.) */
  147. /* ISPLIT (output) INTEGER array, dimension (N) */
  148. /* The splitting points, at which T breaks up into submatrices. */
  149. /* The first submatrix consists of rows/columns 1 to ISPLIT(1), */
  150. /* the second of rows/columns ISPLIT(1)+1 through ISPLIT(2), */
  151. /* etc., and the NSPLIT-th consists of rows/columns */
  152. /* ISPLIT(NSPLIT-1)+1 through ISPLIT(NSPLIT)=N. */
  153. /* (Only the first NSPLIT elements will actually be used, but */
  154. /* since the user cannot know a priori what value NSPLIT will */
  155. /* have, N words must be reserved for ISPLIT.) */
  156. /* WORK (workspace) DOUBLE PRECISION array, dimension (4*N) */
  157. /* IWORK (workspace) INTEGER array, dimension (3*N) */
  158. /* INFO (output) INTEGER */
  159. /* = 0: successful exit */
  160. /* < 0: if INFO = -i, the i-th argument had an illegal value */
  161. /* > 0: some or all of the eigenvalues failed to converge or */
  162. /* were not computed: */
  163. /* =1 or 3: Bisection failed to converge for some */
  164. /* eigenvalues; these eigenvalues are flagged by a */
  165. /* negative block number. The effect is that the */
  166. /* eigenvalues may not be as accurate as the */
  167. /* absolute and relative tolerances. This is */
  168. /* generally caused by unexpectedly inaccurate */
  169. /* arithmetic. */
  170. /* =2 or 3: RANGE='I' only: Not all of the eigenvalues */
  171. /* IL:IU were found. */
  172. /* Effect: M < IU+1-IL */
  173. /* Cause: non-monotonic arithmetic, causing the */
  174. /* Sturm sequence to be non-monotonic. */
  175. /* Cure: recalculate, using RANGE='A', and pick */
  176. /* out eigenvalues IL:IU. In some cases, */
  177. /* increasing the PARAMETER "FUDGE" may */
  178. /* make things work. */
  179. /* = 4: RANGE='I', and the Gershgorin interval */
  180. /* initially used was too small. No eigenvalues */
  181. /* were computed. */
  182. /* Probable cause: your machine has sloppy */
  183. /* floating-point arithmetic. */
  184. /* Cure: Increase the PARAMETER "FUDGE", */
  185. /* recompile, and try again. */
  186. /* Internal Parameters */
  187. /* =================== */
  188. /* RELFAC DOUBLE PRECISION, default = 2.0e0 */
  189. /* The relative tolerance. An interval (a,b] lies within */
  190. /* "relative tolerance" if b-a < RELFAC*ulp*max(|a|,|b|), */
  191. /* where "ulp" is the machine precision (distance from 1 to */
  192. /* the next larger floating point number.) */
  193. /* FUDGE DOUBLE PRECISION, default = 2 */
  194. /* A "fudge factor" to widen the Gershgorin intervals. Ideally, */
  195. /* a value of 1 should work, but on machines with sloppy */
  196. /* arithmetic, this needs to be larger. The default for */
  197. /* publicly released versions should be large enough to handle */
  198. /* the worst machine around. Note that this has no effect */
  199. /* on accuracy of the solution. */
  200. /* ===================================================================== */
  201. /* .. Parameters .. */
  202. /* .. */
  203. /* .. Local Scalars .. */
  204. /* .. */
  205. /* .. Local Arrays .. */
  206. /* .. */
  207. /* .. External Functions .. */
  208. /* .. */
  209. /* .. External Subroutines .. */
  210. /* .. */
  211. /* .. Intrinsic Functions .. */
  212. /* .. */
  213. /* .. Executable Statements .. */
  214. /* Parameter adjustments */
  215. --iwork;
  216. --work;
  217. --isplit;
  218. --iblock;
  219. --w;
  220. --e;
  221. --d__;
  222. /* Function Body */
  223. *info = 0;
  224. /* Decode RANGE */
  225. if (_starpu_lsame_(range, "A")) {
  226. irange = 1;
  227. } else if (_starpu_lsame_(range, "V")) {
  228. irange = 2;
  229. } else if (_starpu_lsame_(range, "I")) {
  230. irange = 3;
  231. } else {
  232. irange = 0;
  233. }
  234. /* Decode ORDER */
  235. if (_starpu_lsame_(order, "B")) {
  236. iorder = 2;
  237. } else if (_starpu_lsame_(order, "E")) {
  238. iorder = 1;
  239. } else {
  240. iorder = 0;
  241. }
  242. /* Check for Errors */
  243. if (irange <= 0) {
  244. *info = -1;
  245. } else if (iorder <= 0) {
  246. *info = -2;
  247. } else if (*n < 0) {
  248. *info = -3;
  249. } else if (irange == 2) {
  250. if (*vl >= *vu) {
  251. *info = -5;
  252. }
  253. } else if (irange == 3 && (*il < 1 || *il > max(1,*n))) {
  254. *info = -6;
  255. } else if (irange == 3 && (*iu < min(*n,*il) || *iu > *n)) {
  256. *info = -7;
  257. }
  258. if (*info != 0) {
  259. i__1 = -(*info);
  260. _starpu_xerbla_("DSTEBZ", &i__1);
  261. return 0;
  262. }
  263. /* Initialize error flags */
  264. *info = 0;
  265. ncnvrg = FALSE_;
  266. toofew = FALSE_;
  267. /* Quick return if possible */
  268. *m = 0;
  269. if (*n == 0) {
  270. return 0;
  271. }
  272. /* Simplifications: */
  273. if (irange == 3 && *il == 1 && *iu == *n) {
  274. irange = 1;
  275. }
  276. /* Get machine constants */
  277. /* NB is the minimum vector length for vector bisection, or 0 */
  278. /* if only scalar is to be done. */
  279. safemn = _starpu_dlamch_("S");
  280. ulp = _starpu_dlamch_("P");
  281. rtoli = ulp * 2.;
  282. nb = _starpu_ilaenv_(&c__1, "DSTEBZ", " ", n, &c_n1, &c_n1, &c_n1);
  283. if (nb <= 1) {
  284. nb = 0;
  285. }
  286. /* Special Case when N=1 */
  287. if (*n == 1) {
  288. *nsplit = 1;
  289. isplit[1] = 1;
  290. if (irange == 2 && (*vl >= d__[1] || *vu < d__[1])) {
  291. *m = 0;
  292. } else {
  293. w[1] = d__[1];
  294. iblock[1] = 1;
  295. *m = 1;
  296. }
  297. return 0;
  298. }
  299. /* Compute Splitting Points */
  300. *nsplit = 1;
  301. work[*n] = 0.;
  302. pivmin = 1.;
  303. /* DIR$ NOVECTOR */
  304. i__1 = *n;
  305. for (j = 2; j <= i__1; ++j) {
  306. /* Computing 2nd power */
  307. d__1 = e[j - 1];
  308. tmp1 = d__1 * d__1;
  309. /* Computing 2nd power */
  310. d__2 = ulp;
  311. if ((d__1 = d__[j] * d__[j - 1], abs(d__1)) * (d__2 * d__2) + safemn
  312. > tmp1) {
  313. isplit[*nsplit] = j - 1;
  314. ++(*nsplit);
  315. work[j - 1] = 0.;
  316. } else {
  317. work[j - 1] = tmp1;
  318. pivmin = max(pivmin,tmp1);
  319. }
  320. /* L10: */
  321. }
  322. isplit[*nsplit] = *n;
  323. pivmin *= safemn;
  324. /* Compute Interval and ATOLI */
  325. if (irange == 3) {
  326. /* RANGE='I': Compute the interval containing eigenvalues */
  327. /* IL through IU. */
  328. /* Compute Gershgorin interval for entire (split) matrix */
  329. /* and use it as the initial interval */
  330. gu = d__[1];
  331. gl = d__[1];
  332. tmp1 = 0.;
  333. i__1 = *n - 1;
  334. for (j = 1; j <= i__1; ++j) {
  335. tmp2 = sqrt(work[j]);
  336. /* Computing MAX */
  337. d__1 = gu, d__2 = d__[j] + tmp1 + tmp2;
  338. gu = max(d__1,d__2);
  339. /* Computing MIN */
  340. d__1 = gl, d__2 = d__[j] - tmp1 - tmp2;
  341. gl = min(d__1,d__2);
  342. tmp1 = tmp2;
  343. /* L20: */
  344. }
  345. /* Computing MAX */
  346. d__1 = gu, d__2 = d__[*n] + tmp1;
  347. gu = max(d__1,d__2);
  348. /* Computing MIN */
  349. d__1 = gl, d__2 = d__[*n] - tmp1;
  350. gl = min(d__1,d__2);
  351. /* Computing MAX */
  352. d__1 = abs(gl), d__2 = abs(gu);
  353. tnorm = max(d__1,d__2);
  354. gl = gl - tnorm * 2.1 * ulp * *n - pivmin * 4.2000000000000002;
  355. gu = gu + tnorm * 2.1 * ulp * *n + pivmin * 2.1;
  356. /* Compute Iteration parameters */
  357. itmax = (integer) ((log(tnorm + pivmin) - log(pivmin)) / log(2.)) + 2;
  358. if (*abstol <= 0.) {
  359. atoli = ulp * tnorm;
  360. } else {
  361. atoli = *abstol;
  362. }
  363. work[*n + 1] = gl;
  364. work[*n + 2] = gl;
  365. work[*n + 3] = gu;
  366. work[*n + 4] = gu;
  367. work[*n + 5] = gl;
  368. work[*n + 6] = gu;
  369. iwork[1] = -1;
  370. iwork[2] = -1;
  371. iwork[3] = *n + 1;
  372. iwork[4] = *n + 1;
  373. iwork[5] = *il - 1;
  374. iwork[6] = *iu;
  375. _starpu_dlaebz_(&c__3, &itmax, n, &c__2, &c__2, &nb, &atoli, &rtoli, &pivmin,
  376. &d__[1], &e[1], &work[1], &iwork[5], &work[*n + 1], &work[*n
  377. + 5], &iout, &iwork[1], &w[1], &iblock[1], &iinfo);
  378. if (iwork[6] == *iu) {
  379. wl = work[*n + 1];
  380. wlu = work[*n + 3];
  381. nwl = iwork[1];
  382. wu = work[*n + 4];
  383. wul = work[*n + 2];
  384. nwu = iwork[4];
  385. } else {
  386. wl = work[*n + 2];
  387. wlu = work[*n + 4];
  388. nwl = iwork[2];
  389. wu = work[*n + 3];
  390. wul = work[*n + 1];
  391. nwu = iwork[3];
  392. }
  393. if (nwl < 0 || nwl >= *n || nwu < 1 || nwu > *n) {
  394. *info = 4;
  395. return 0;
  396. }
  397. } else {
  398. /* RANGE='A' or 'V' -- Set ATOLI */
  399. /* Computing MAX */
  400. d__3 = abs(d__[1]) + abs(e[1]), d__4 = (d__1 = d__[*n], abs(d__1)) + (
  401. d__2 = e[*n - 1], abs(d__2));
  402. tnorm = max(d__3,d__4);
  403. i__1 = *n - 1;
  404. for (j = 2; j <= i__1; ++j) {
  405. /* Computing MAX */
  406. d__4 = tnorm, d__5 = (d__1 = d__[j], abs(d__1)) + (d__2 = e[j - 1]
  407. , abs(d__2)) + (d__3 = e[j], abs(d__3));
  408. tnorm = max(d__4,d__5);
  409. /* L30: */
  410. }
  411. if (*abstol <= 0.) {
  412. atoli = ulp * tnorm;
  413. } else {
  414. atoli = *abstol;
  415. }
  416. if (irange == 2) {
  417. wl = *vl;
  418. wu = *vu;
  419. } else {
  420. wl = 0.;
  421. wu = 0.;
  422. }
  423. }
  424. /* Find Eigenvalues -- Loop Over Blocks and recompute NWL and NWU. */
  425. /* NWL accumulates the number of eigenvalues .le. WL, */
  426. /* NWU accumulates the number of eigenvalues .le. WU */
  427. *m = 0;
  428. iend = 0;
  429. *info = 0;
  430. nwl = 0;
  431. nwu = 0;
  432. i__1 = *nsplit;
  433. for (jb = 1; jb <= i__1; ++jb) {
  434. ioff = iend;
  435. ibegin = ioff + 1;
  436. iend = isplit[jb];
  437. in = iend - ioff;
  438. if (in == 1) {
  439. /* Special Case -- IN=1 */
  440. if (irange == 1 || wl >= d__[ibegin] - pivmin) {
  441. ++nwl;
  442. }
  443. if (irange == 1 || wu >= d__[ibegin] - pivmin) {
  444. ++nwu;
  445. }
  446. if (irange == 1 || wl < d__[ibegin] - pivmin && wu >= d__[ibegin]
  447. - pivmin) {
  448. ++(*m);
  449. w[*m] = d__[ibegin];
  450. iblock[*m] = jb;
  451. }
  452. } else {
  453. /* General Case -- IN > 1 */
  454. /* Compute Gershgorin Interval */
  455. /* and use it as the initial interval */
  456. gu = d__[ibegin];
  457. gl = d__[ibegin];
  458. tmp1 = 0.;
  459. i__2 = iend - 1;
  460. for (j = ibegin; j <= i__2; ++j) {
  461. tmp2 = (d__1 = e[j], abs(d__1));
  462. /* Computing MAX */
  463. d__1 = gu, d__2 = d__[j] + tmp1 + tmp2;
  464. gu = max(d__1,d__2);
  465. /* Computing MIN */
  466. d__1 = gl, d__2 = d__[j] - tmp1 - tmp2;
  467. gl = min(d__1,d__2);
  468. tmp1 = tmp2;
  469. /* L40: */
  470. }
  471. /* Computing MAX */
  472. d__1 = gu, d__2 = d__[iend] + tmp1;
  473. gu = max(d__1,d__2);
  474. /* Computing MIN */
  475. d__1 = gl, d__2 = d__[iend] - tmp1;
  476. gl = min(d__1,d__2);
  477. /* Computing MAX */
  478. d__1 = abs(gl), d__2 = abs(gu);
  479. bnorm = max(d__1,d__2);
  480. gl = gl - bnorm * 2.1 * ulp * in - pivmin * 2.1;
  481. gu = gu + bnorm * 2.1 * ulp * in + pivmin * 2.1;
  482. /* Compute ATOLI for the current submatrix */
  483. if (*abstol <= 0.) {
  484. /* Computing MAX */
  485. d__1 = abs(gl), d__2 = abs(gu);
  486. atoli = ulp * max(d__1,d__2);
  487. } else {
  488. atoli = *abstol;
  489. }
  490. if (irange > 1) {
  491. if (gu < wl) {
  492. nwl += in;
  493. nwu += in;
  494. goto L70;
  495. }
  496. gl = max(gl,wl);
  497. gu = min(gu,wu);
  498. if (gl >= gu) {
  499. goto L70;
  500. }
  501. }
  502. /* Set Up Initial Interval */
  503. work[*n + 1] = gl;
  504. work[*n + in + 1] = gu;
  505. _starpu_dlaebz_(&c__1, &c__0, &in, &in, &c__1, &nb, &atoli, &rtoli, &
  506. pivmin, &d__[ibegin], &e[ibegin], &work[ibegin], idumma, &
  507. work[*n + 1], &work[*n + (in << 1) + 1], &im, &iwork[1], &
  508. w[*m + 1], &iblock[*m + 1], &iinfo);
  509. nwl += iwork[1];
  510. nwu += iwork[in + 1];
  511. iwoff = *m - iwork[1];
  512. /* Compute Eigenvalues */
  513. itmax = (integer) ((log(gu - gl + pivmin) - log(pivmin)) / log(2.)
  514. ) + 2;
  515. _starpu_dlaebz_(&c__2, &itmax, &in, &in, &c__1, &nb, &atoli, &rtoli, &
  516. pivmin, &d__[ibegin], &e[ibegin], &work[ibegin], idumma, &
  517. work[*n + 1], &work[*n + (in << 1) + 1], &iout, &iwork[1],
  518. &w[*m + 1], &iblock[*m + 1], &iinfo);
  519. /* Copy Eigenvalues Into W and IBLOCK */
  520. /* Use -JB for block number for unconverged eigenvalues. */
  521. i__2 = iout;
  522. for (j = 1; j <= i__2; ++j) {
  523. tmp1 = (work[j + *n] + work[j + in + *n]) * .5;
  524. /* Flag non-convergence. */
  525. if (j > iout - iinfo) {
  526. ncnvrg = TRUE_;
  527. ib = -jb;
  528. } else {
  529. ib = jb;
  530. }
  531. i__3 = iwork[j + in] + iwoff;
  532. for (je = iwork[j] + 1 + iwoff; je <= i__3; ++je) {
  533. w[je] = tmp1;
  534. iblock[je] = ib;
  535. /* L50: */
  536. }
  537. /* L60: */
  538. }
  539. *m += im;
  540. }
  541. L70:
  542. ;
  543. }
  544. /* If RANGE='I', then (WL,WU) contains eigenvalues NWL+1,...,NWU */
  545. /* If NWL+1 < IL or NWU > IU, discard extra eigenvalues. */
  546. if (irange == 3) {
  547. im = 0;
  548. idiscl = *il - 1 - nwl;
  549. idiscu = nwu - *iu;
  550. if (idiscl > 0 || idiscu > 0) {
  551. i__1 = *m;
  552. for (je = 1; je <= i__1; ++je) {
  553. if (w[je] <= wlu && idiscl > 0) {
  554. --idiscl;
  555. } else if (w[je] >= wul && idiscu > 0) {
  556. --idiscu;
  557. } else {
  558. ++im;
  559. w[im] = w[je];
  560. iblock[im] = iblock[je];
  561. }
  562. /* L80: */
  563. }
  564. *m = im;
  565. }
  566. if (idiscl > 0 || idiscu > 0) {
  567. /* Code to deal with effects of bad arithmetic: */
  568. /* Some low eigenvalues to be discarded are not in (WL,WLU], */
  569. /* or high eigenvalues to be discarded are not in (WUL,WU] */
  570. /* so just kill off the smallest IDISCL/largest IDISCU */
  571. /* eigenvalues, by simply finding the smallest/largest */
  572. /* eigenvalue(s). */
  573. /* (If N(w) is monotone non-decreasing, this should never */
  574. /* happen.) */
  575. if (idiscl > 0) {
  576. wkill = wu;
  577. i__1 = idiscl;
  578. for (jdisc = 1; jdisc <= i__1; ++jdisc) {
  579. iw = 0;
  580. i__2 = *m;
  581. for (je = 1; je <= i__2; ++je) {
  582. if (iblock[je] != 0 && (w[je] < wkill || iw == 0)) {
  583. iw = je;
  584. wkill = w[je];
  585. }
  586. /* L90: */
  587. }
  588. iblock[iw] = 0;
  589. /* L100: */
  590. }
  591. }
  592. if (idiscu > 0) {
  593. wkill = wl;
  594. i__1 = idiscu;
  595. for (jdisc = 1; jdisc <= i__1; ++jdisc) {
  596. iw = 0;
  597. i__2 = *m;
  598. for (je = 1; je <= i__2; ++je) {
  599. if (iblock[je] != 0 && (w[je] > wkill || iw == 0)) {
  600. iw = je;
  601. wkill = w[je];
  602. }
  603. /* L110: */
  604. }
  605. iblock[iw] = 0;
  606. /* L120: */
  607. }
  608. }
  609. im = 0;
  610. i__1 = *m;
  611. for (je = 1; je <= i__1; ++je) {
  612. if (iblock[je] != 0) {
  613. ++im;
  614. w[im] = w[je];
  615. iblock[im] = iblock[je];
  616. }
  617. /* L130: */
  618. }
  619. *m = im;
  620. }
  621. if (idiscl < 0 || idiscu < 0) {
  622. toofew = TRUE_;
  623. }
  624. }
  625. /* If ORDER='B', do nothing -- the eigenvalues are already sorted */
  626. /* by block. */
  627. /* If ORDER='E', sort the eigenvalues from smallest to largest */
  628. if (iorder == 1 && *nsplit > 1) {
  629. i__1 = *m - 1;
  630. for (je = 1; je <= i__1; ++je) {
  631. ie = 0;
  632. tmp1 = w[je];
  633. i__2 = *m;
  634. for (j = je + 1; j <= i__2; ++j) {
  635. if (w[j] < tmp1) {
  636. ie = j;
  637. tmp1 = w[j];
  638. }
  639. /* L140: */
  640. }
  641. if (ie != 0) {
  642. itmp1 = iblock[ie];
  643. w[ie] = w[je];
  644. iblock[ie] = iblock[je];
  645. w[je] = tmp1;
  646. iblock[je] = itmp1;
  647. }
  648. /* L150: */
  649. }
  650. }
  651. *info = 0;
  652. if (ncnvrg) {
  653. ++(*info);
  654. }
  655. if (toofew) {
  656. *info += 2;
  657. }
  658. return 0;
  659. /* End of DSTEBZ */
  660. } /* _starpu_dstebz_ */