00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "f2c.h"
00014 #include "blaswrap.h"
00015
00016
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 int sstebz_(char *range, char *order, integer *n, real *vl,
00025 real *vu, integer *il, integer *iu, real *abstol, real *d__, real *e,
00026 integer *m, integer *nsplit, real *w, integer *iblock, integer *
00027 isplit, real *work, integer *iwork, integer *info)
00028 {
00029
00030 integer i__1, i__2, i__3;
00031 real r__1, r__2, r__3, r__4, r__5;
00032
00033
00034 double sqrt(doublereal), log(doublereal);
00035
00036
00037 integer j, ib, jb, ie, je, nb;
00038 real gl;
00039 integer im, in;
00040 real gu;
00041 integer iw;
00042 real wl, wu;
00043 integer nwl;
00044 real ulp, wlu, wul;
00045 integer nwu;
00046 real tmp1, tmp2;
00047 integer iend, ioff, iout, itmp1, jdisc;
00048 extern logical lsame_(char *, char *);
00049 integer iinfo;
00050 real atoli;
00051 integer iwoff;
00052 real bnorm;
00053 integer itmax;
00054 real wkill, rtoli, tnorm;
00055 integer ibegin, irange, idiscl;
00056 extern doublereal slamch_(char *);
00057 real safemn;
00058 integer idumma[1];
00059 extern int xerbla_(char *, integer *);
00060 extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
00061 integer *, integer *);
00062 integer idiscu;
00063 extern int slaebz_(integer *, integer *, integer *,
00064 integer *, integer *, integer *, real *, real *, real *, real *,
00065 real *, real *, integer *, real *, real *, integer *, integer *,
00066 real *, integer *, integer *);
00067 integer iorder;
00068 logical ncnvrg;
00069 real pivmin;
00070 logical toofew;
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251 --iwork;
00252 --work;
00253 --isplit;
00254 --iblock;
00255 --w;
00256 --e;
00257 --d__;
00258
00259
00260 *info = 0;
00261
00262
00263
00264 if (lsame_(range, "A")) {
00265 irange = 1;
00266 } else if (lsame_(range, "V")) {
00267 irange = 2;
00268 } else if (lsame_(range, "I")) {
00269 irange = 3;
00270 } else {
00271 irange = 0;
00272 }
00273
00274
00275
00276 if (lsame_(order, "B")) {
00277 iorder = 2;
00278 } else if (lsame_(order, "E")) {
00279 iorder = 1;
00280 } else {
00281 iorder = 0;
00282 }
00283
00284
00285
00286 if (irange <= 0) {
00287 *info = -1;
00288 } else if (iorder <= 0) {
00289 *info = -2;
00290 } else if (*n < 0) {
00291 *info = -3;
00292 } else if (irange == 2) {
00293 if (*vl >= *vu) {
00294 *info = -5;
00295 }
00296 } else if (irange == 3 && (*il < 1 || *il > max(1,*n))) {
00297 *info = -6;
00298 } else if (irange == 3 && (*iu < min(*n,*il) || *iu > *n)) {
00299 *info = -7;
00300 }
00301
00302 if (*info != 0) {
00303 i__1 = -(*info);
00304 xerbla_("SSTEBZ", &i__1);
00305 return 0;
00306 }
00307
00308
00309
00310 *info = 0;
00311 ncnvrg = FALSE_;
00312 toofew = FALSE_;
00313
00314
00315
00316 *m = 0;
00317 if (*n == 0) {
00318 return 0;
00319 }
00320
00321
00322
00323 if (irange == 3 && *il == 1 && *iu == *n) {
00324 irange = 1;
00325 }
00326
00327
00328
00329
00330
00331 safemn = slamch_("S");
00332 ulp = slamch_("P");
00333 rtoli = ulp * 2.f;
00334 nb = ilaenv_(&c__1, "SSTEBZ", " ", n, &c_n1, &c_n1, &c_n1);
00335 if (nb <= 1) {
00336 nb = 0;
00337 }
00338
00339
00340
00341 if (*n == 1) {
00342 *nsplit = 1;
00343 isplit[1] = 1;
00344 if (irange == 2 && (*vl >= d__[1] || *vu < d__[1])) {
00345 *m = 0;
00346 } else {
00347 w[1] = d__[1];
00348 iblock[1] = 1;
00349 *m = 1;
00350 }
00351 return 0;
00352 }
00353
00354
00355
00356 *nsplit = 1;
00357 work[*n] = 0.f;
00358 pivmin = 1.f;
00359
00360
00361 i__1 = *n;
00362 for (j = 2; j <= i__1; ++j) {
00363
00364 r__1 = e[j - 1];
00365 tmp1 = r__1 * r__1;
00366
00367 r__2 = ulp;
00368 if ((r__1 = d__[j] * d__[j - 1], dabs(r__1)) * (r__2 * r__2) + safemn
00369 > tmp1) {
00370 isplit[*nsplit] = j - 1;
00371 ++(*nsplit);
00372 work[j - 1] = 0.f;
00373 } else {
00374 work[j - 1] = tmp1;
00375 pivmin = dmax(pivmin,tmp1);
00376 }
00377
00378 }
00379 isplit[*nsplit] = *n;
00380 pivmin *= safemn;
00381
00382
00383
00384 if (irange == 3) {
00385
00386
00387
00388
00389
00390
00391
00392 gu = d__[1];
00393 gl = d__[1];
00394 tmp1 = 0.f;
00395
00396 i__1 = *n - 1;
00397 for (j = 1; j <= i__1; ++j) {
00398 tmp2 = sqrt(work[j]);
00399
00400 r__1 = gu, r__2 = d__[j] + tmp1 + tmp2;
00401 gu = dmax(r__1,r__2);
00402
00403 r__1 = gl, r__2 = d__[j] - tmp1 - tmp2;
00404 gl = dmin(r__1,r__2);
00405 tmp1 = tmp2;
00406
00407 }
00408
00409
00410 r__1 = gu, r__2 = d__[*n] + tmp1;
00411 gu = dmax(r__1,r__2);
00412
00413 r__1 = gl, r__2 = d__[*n] - tmp1;
00414 gl = dmin(r__1,r__2);
00415
00416 r__1 = dabs(gl), r__2 = dabs(gu);
00417 tnorm = dmax(r__1,r__2);
00418 gl = gl - tnorm * 2.1f * ulp * *n - pivmin * 4.2000000000000002f;
00419 gu = gu + tnorm * 2.1f * ulp * *n + pivmin * 2.1f;
00420
00421
00422
00423 itmax = (integer) ((log(tnorm + pivmin) - log(pivmin)) / log(2.f)) +
00424 2;
00425 if (*abstol <= 0.f) {
00426 atoli = ulp * tnorm;
00427 } else {
00428 atoli = *abstol;
00429 }
00430
00431 work[*n + 1] = gl;
00432 work[*n + 2] = gl;
00433 work[*n + 3] = gu;
00434 work[*n + 4] = gu;
00435 work[*n + 5] = gl;
00436 work[*n + 6] = gu;
00437 iwork[1] = -1;
00438 iwork[2] = -1;
00439 iwork[3] = *n + 1;
00440 iwork[4] = *n + 1;
00441 iwork[5] = *il - 1;
00442 iwork[6] = *iu;
00443
00444 slaebz_(&c__3, &itmax, n, &c__2, &c__2, &nb, &atoli, &rtoli, &pivmin,
00445 &d__[1], &e[1], &work[1], &iwork[5], &work[*n + 1], &work[*n
00446 + 5], &iout, &iwork[1], &w[1], &iblock[1], &iinfo);
00447
00448 if (iwork[6] == *iu) {
00449 wl = work[*n + 1];
00450 wlu = work[*n + 3];
00451 nwl = iwork[1];
00452 wu = work[*n + 4];
00453 wul = work[*n + 2];
00454 nwu = iwork[4];
00455 } else {
00456 wl = work[*n + 2];
00457 wlu = work[*n + 4];
00458 nwl = iwork[2];
00459 wu = work[*n + 3];
00460 wul = work[*n + 1];
00461 nwu = iwork[3];
00462 }
00463
00464 if (nwl < 0 || nwl >= *n || nwu < 1 || nwu > *n) {
00465 *info = 4;
00466 return 0;
00467 }
00468 } else {
00469
00470
00471
00472
00473 r__3 = dabs(d__[1]) + dabs(e[1]), r__4 = (r__1 = d__[*n], dabs(r__1))
00474 + (r__2 = e[*n - 1], dabs(r__2));
00475 tnorm = dmax(r__3,r__4);
00476
00477 i__1 = *n - 1;
00478 for (j = 2; j <= i__1; ++j) {
00479
00480 r__4 = tnorm, r__5 = (r__1 = d__[j], dabs(r__1)) + (r__2 = e[j -
00481 1], dabs(r__2)) + (r__3 = e[j], dabs(r__3));
00482 tnorm = dmax(r__4,r__5);
00483
00484 }
00485
00486 if (*abstol <= 0.f) {
00487 atoli = ulp * tnorm;
00488 } else {
00489 atoli = *abstol;
00490 }
00491
00492 if (irange == 2) {
00493 wl = *vl;
00494 wu = *vu;
00495 } else {
00496 wl = 0.f;
00497 wu = 0.f;
00498 }
00499 }
00500
00501
00502
00503
00504
00505 *m = 0;
00506 iend = 0;
00507 *info = 0;
00508 nwl = 0;
00509 nwu = 0;
00510
00511 i__1 = *nsplit;
00512 for (jb = 1; jb <= i__1; ++jb) {
00513 ioff = iend;
00514 ibegin = ioff + 1;
00515 iend = isplit[jb];
00516 in = iend - ioff;
00517
00518 if (in == 1) {
00519
00520
00521
00522 if (irange == 1 || wl >= d__[ibegin] - pivmin) {
00523 ++nwl;
00524 }
00525 if (irange == 1 || wu >= d__[ibegin] - pivmin) {
00526 ++nwu;
00527 }
00528 if (irange == 1 || wl < d__[ibegin] - pivmin && wu >= d__[ibegin]
00529 - pivmin) {
00530 ++(*m);
00531 w[*m] = d__[ibegin];
00532 iblock[*m] = jb;
00533 }
00534 } else {
00535
00536
00537
00538
00539
00540
00541 gu = d__[ibegin];
00542 gl = d__[ibegin];
00543 tmp1 = 0.f;
00544
00545 i__2 = iend - 1;
00546 for (j = ibegin; j <= i__2; ++j) {
00547 tmp2 = (r__1 = e[j], dabs(r__1));
00548
00549 r__1 = gu, r__2 = d__[j] + tmp1 + tmp2;
00550 gu = dmax(r__1,r__2);
00551
00552 r__1 = gl, r__2 = d__[j] - tmp1 - tmp2;
00553 gl = dmin(r__1,r__2);
00554 tmp1 = tmp2;
00555
00556 }
00557
00558
00559 r__1 = gu, r__2 = d__[iend] + tmp1;
00560 gu = dmax(r__1,r__2);
00561
00562 r__1 = gl, r__2 = d__[iend] - tmp1;
00563 gl = dmin(r__1,r__2);
00564
00565 r__1 = dabs(gl), r__2 = dabs(gu);
00566 bnorm = dmax(r__1,r__2);
00567 gl = gl - bnorm * 2.1f * ulp * in - pivmin * 2.1f;
00568 gu = gu + bnorm * 2.1f * ulp * in + pivmin * 2.1f;
00569
00570
00571
00572 if (*abstol <= 0.f) {
00573
00574 r__1 = dabs(gl), r__2 = dabs(gu);
00575 atoli = ulp * dmax(r__1,r__2);
00576 } else {
00577 atoli = *abstol;
00578 }
00579
00580 if (irange > 1) {
00581 if (gu < wl) {
00582 nwl += in;
00583 nwu += in;
00584 goto L70;
00585 }
00586 gl = dmax(gl,wl);
00587 gu = dmin(gu,wu);
00588 if (gl >= gu) {
00589 goto L70;
00590 }
00591 }
00592
00593
00594
00595 work[*n + 1] = gl;
00596 work[*n + in + 1] = gu;
00597 slaebz_(&c__1, &c__0, &in, &in, &c__1, &nb, &atoli, &rtoli, &
00598 pivmin, &d__[ibegin], &e[ibegin], &work[ibegin], idumma, &
00599 work[*n + 1], &work[*n + (in << 1) + 1], &im, &iwork[1], &
00600 w[*m + 1], &iblock[*m + 1], &iinfo);
00601
00602 nwl += iwork[1];
00603 nwu += iwork[in + 1];
00604 iwoff = *m - iwork[1];
00605
00606
00607
00608 itmax = (integer) ((log(gu - gl + pivmin) - log(pivmin)) / log(
00609 2.f)) + 2;
00610 slaebz_(&c__2, &itmax, &in, &in, &c__1, &nb, &atoli, &rtoli, &
00611 pivmin, &d__[ibegin], &e[ibegin], &work[ibegin], idumma, &
00612 work[*n + 1], &work[*n + (in << 1) + 1], &iout, &iwork[1],
00613 &w[*m + 1], &iblock[*m + 1], &iinfo);
00614
00615
00616
00617
00618 i__2 = iout;
00619 for (j = 1; j <= i__2; ++j) {
00620 tmp1 = (work[j + *n] + work[j + in + *n]) * .5f;
00621
00622
00623
00624 if (j > iout - iinfo) {
00625 ncnvrg = TRUE_;
00626 ib = -jb;
00627 } else {
00628 ib = jb;
00629 }
00630 i__3 = iwork[j + in] + iwoff;
00631 for (je = iwork[j] + 1 + iwoff; je <= i__3; ++je) {
00632 w[je] = tmp1;
00633 iblock[je] = ib;
00634
00635 }
00636
00637 }
00638
00639 *m += im;
00640 }
00641 L70:
00642 ;
00643 }
00644
00645
00646
00647
00648 if (irange == 3) {
00649 im = 0;
00650 idiscl = *il - 1 - nwl;
00651 idiscu = nwu - *iu;
00652
00653 if (idiscl > 0 || idiscu > 0) {
00654 i__1 = *m;
00655 for (je = 1; je <= i__1; ++je) {
00656 if (w[je] <= wlu && idiscl > 0) {
00657 --idiscl;
00658 } else if (w[je] >= wul && idiscu > 0) {
00659 --idiscu;
00660 } else {
00661 ++im;
00662 w[im] = w[je];
00663 iblock[im] = iblock[je];
00664 }
00665
00666 }
00667 *m = im;
00668 }
00669 if (idiscl > 0 || idiscu > 0) {
00670
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
00681 if (idiscl > 0) {
00682 wkill = wu;
00683 i__1 = idiscl;
00684 for (jdisc = 1; jdisc <= i__1; ++jdisc) {
00685 iw = 0;
00686 i__2 = *m;
00687 for (je = 1; je <= i__2; ++je) {
00688 if (iblock[je] != 0 && (w[je] < wkill || iw == 0)) {
00689 iw = je;
00690 wkill = w[je];
00691 }
00692
00693 }
00694 iblock[iw] = 0;
00695
00696 }
00697 }
00698 if (idiscu > 0) {
00699
00700 wkill = wl;
00701 i__1 = idiscu;
00702 for (jdisc = 1; jdisc <= i__1; ++jdisc) {
00703 iw = 0;
00704 i__2 = *m;
00705 for (je = 1; je <= i__2; ++je) {
00706 if (iblock[je] != 0 && (w[je] > wkill || iw == 0)) {
00707 iw = je;
00708 wkill = w[je];
00709 }
00710
00711 }
00712 iblock[iw] = 0;
00713
00714 }
00715 }
00716 im = 0;
00717 i__1 = *m;
00718 for (je = 1; je <= i__1; ++je) {
00719 if (iblock[je] != 0) {
00720 ++im;
00721 w[im] = w[je];
00722 iblock[im] = iblock[je];
00723 }
00724
00725 }
00726 *m = im;
00727 }
00728 if (idiscl < 0 || idiscu < 0) {
00729 toofew = TRUE_;
00730 }
00731 }
00732
00733
00734
00735
00736
00737 if (iorder == 1 && *nsplit > 1) {
00738 i__1 = *m - 1;
00739 for (je = 1; je <= i__1; ++je) {
00740 ie = 0;
00741 tmp1 = w[je];
00742 i__2 = *m;
00743 for (j = je + 1; j <= i__2; ++j) {
00744 if (w[j] < tmp1) {
00745 ie = j;
00746 tmp1 = w[j];
00747 }
00748
00749 }
00750
00751 if (ie != 0) {
00752 itmp1 = iblock[ie];
00753 w[ie] = w[je];
00754 iblock[ie] = iblock[je];
00755 w[je] = tmp1;
00756 iblock[je] = itmp1;
00757 }
00758
00759 }
00760 }
00761
00762 *info = 0;
00763 if (ncnvrg) {
00764 ++(*info);
00765 }
00766 if (toofew) {
00767 *info += 2;
00768 }
00769 return 0;
00770
00771
00772
00773 }