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 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
00031 integer i__1, i__2, i__3;
00032 doublereal d__1, d__2, d__3, d__4, d__5;
00033
00034
00035 double sqrt(doublereal), log(doublereal);
00036
00037
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 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 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
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
00252
00253 --iwork;
00254 --work;
00255 --isplit;
00256 --iblock;
00257 --w;
00258 --e;
00259 --d__;
00260
00261
00262 *info = 0;
00263
00264
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
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
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
00311
00312 *info = 0;
00313 ncnvrg = FALSE_;
00314 toofew = FALSE_;
00315
00316
00317
00318 *m = 0;
00319 if (*n == 0) {
00320 return 0;
00321 }
00322
00323
00324
00325 if (irange == 3 && *il == 1 && *iu == *n) {
00326 irange = 1;
00327 }
00328
00329
00330
00331
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
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
00357
00358 *nsplit = 1;
00359 work[*n] = 0.;
00360 pivmin = 1.;
00361
00362
00363 i__1 = *n;
00364 for (j = 2; j <= i__1; ++j) {
00365
00366 d__1 = e[j - 1];
00367 tmp1 = d__1 * d__1;
00368
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
00380 }
00381 isplit[*nsplit] = *n;
00382 pivmin *= safemn;
00383
00384
00385
00386 if (irange == 3) {
00387
00388
00389
00390
00391
00392
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
00402 d__1 = gu, d__2 = d__[j] + tmp1 + tmp2;
00403 gu = max(d__1,d__2);
00404
00405 d__1 = gl, d__2 = d__[j] - tmp1 - tmp2;
00406 gl = min(d__1,d__2);
00407 tmp1 = tmp2;
00408
00409 }
00410
00411
00412 d__1 = gu, d__2 = d__[*n] + tmp1;
00413 gu = max(d__1,d__2);
00414
00415 d__1 = gl, d__2 = d__[*n] - tmp1;
00416 gl = min(d__1,d__2);
00417
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
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
00472
00473
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
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
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
00503
00504
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
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
00538
00539
00540
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
00550 d__1 = gu, d__2 = d__[j] + tmp1 + tmp2;
00551 gu = max(d__1,d__2);
00552
00553 d__1 = gl, d__2 = d__[j] - tmp1 - tmp2;
00554 gl = min(d__1,d__2);
00555 tmp1 = tmp2;
00556
00557 }
00558
00559
00560 d__1 = gu, d__2 = d__[iend] + tmp1;
00561 gu = max(d__1,d__2);
00562
00563 d__1 = gl, d__2 = d__[iend] - tmp1;
00564 gl = min(d__1,d__2);
00565
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
00572
00573 if (*abstol <= 0.) {
00574
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
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
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
00617
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
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
00636 }
00637
00638 }
00639
00640 *m += im;
00641 }
00642 L70:
00643 ;
00644 }
00645
00646
00647
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
00667 }
00668 *m = im;
00669 }
00670 if (idiscl > 0 || idiscu > 0) {
00671
00672
00673
00674
00675
00676
00677
00678
00679
00680
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
00694 }
00695 iblock[iw] = 0;
00696
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
00712 }
00713 iblock[iw] = 0;
00714
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
00726 }
00727 *m = im;
00728 }
00729 if (idiscl < 0 || idiscu < 0) {
00730 toofew = TRUE_;
00731 }
00732 }
00733
00734
00735
00736
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
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
00760 }
00761 }
00762
00763 *info = 0;
00764 if (ncnvrg) {
00765 ++(*info);
00766 }
00767 if (toofew) {
00768 *info += 2;
00769 }
00770 return 0;
00771
00772
00773
00774 }