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__2 = 2;
00020
00021 int slarre_(char *range, integer *n, real *vl, real *vu,
00022 integer *il, integer *iu, real *d__, real *e, real *e2, real *rtol1,
00023 real *rtol2, real *spltol, integer *nsplit, integer *isplit, integer *
00024 m, real *w, real *werr, real *wgap, integer *iblock, integer *indexw,
00025 real *gers, real *pivmin, real *work, integer *iwork, integer *info)
00026 {
00027
00028 integer i__1, i__2;
00029 real r__1, r__2, r__3;
00030
00031
00032 double sqrt(doublereal), log(doublereal);
00033
00034
00035 integer i__, j;
00036 real s1, s2;
00037 integer mb;
00038 real gl;
00039 integer in, mm;
00040 real gu;
00041 integer cnt;
00042 real eps, tau, tmp, rtl;
00043 integer cnt1, cnt2;
00044 real tmp1, eabs;
00045 integer iend, jblk;
00046 real eold;
00047 integer indl;
00048 real dmax__, emax;
00049 integer wend, idum, indu;
00050 real rtol;
00051 integer iseed[4];
00052 real avgap, sigma;
00053 extern logical lsame_(char *, char *);
00054 integer iinfo;
00055 logical norep;
00056 extern int scopy_(integer *, real *, integer *, real *,
00057 integer *), slasq2_(integer *, real *, integer *);
00058 integer ibegin;
00059 logical forceb;
00060 integer irange;
00061 real sgndef;
00062 extern doublereal slamch_(char *);
00063 integer wbegin;
00064 real safmin, spdiam;
00065 extern int slarra_(integer *, real *, real *, real *,
00066 real *, real *, integer *, integer *, integer *);
00067 logical usedqd;
00068 real clwdth, isleft;
00069 extern int slarrb_(integer *, real *, real *, integer *,
00070 integer *, real *, real *, integer *, real *, real *, real *,
00071 real *, integer *, real *, real *, integer *, integer *), slarrc_(
00072 char *, integer *, real *, real *, real *, real *, real *,
00073 integer *, integer *, integer *, integer *), slarrd_(char
00074 *, char *, integer *, real *, real *, integer *, integer *, real *
00075 , real *, real *, real *, real *, real *, integer *, integer *,
00076 integer *, real *, real *, real *, real *, integer *, integer *,
00077 real *, integer *, integer *), slarrk_(integer *,
00078 integer *, real *, real *, real *, real *, real *, real *, real *,
00079 real *, integer *);
00080 real isrght, bsrtol, dpivot;
00081 extern int slarnv_(integer *, integer *, integer *, real
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
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267 --iwork;
00268 --work;
00269 --gers;
00270 --indexw;
00271 --iblock;
00272 --wgap;
00273 --werr;
00274 --w;
00275 --isplit;
00276 --e2;
00277 --e;
00278 --d__;
00279
00280
00281 *info = 0;
00282
00283
00284
00285 if (lsame_(range, "A")) {
00286 irange = 1;
00287 } else if (lsame_(range, "V")) {
00288 irange = 3;
00289 } else if (lsame_(range, "I")) {
00290 irange = 2;
00291 }
00292 *m = 0;
00293
00294 safmin = slamch_("S");
00295 eps = slamch_("P");
00296
00297 rtl = eps * 100.f;
00298
00299
00300
00301
00302 bsrtol = sqrt(eps) * 5e-4f;
00303
00304 if (*n == 1) {
00305 if (irange == 1 || irange == 3 && d__[1] > *vl && d__[1] <= *vu ||
00306 irange == 2 && *il == 1 && *iu == 1) {
00307 *m = 1;
00308 w[1] = d__[1];
00309
00310 werr[1] = 0.f;
00311 wgap[1] = 0.f;
00312 iblock[1] = 1;
00313 indexw[1] = 1;
00314 gers[1] = d__[1];
00315 gers[2] = d__[1];
00316 }
00317
00318 e[1] = 0.f;
00319 return 0;
00320 }
00321
00322
00323
00324
00325 gl = d__[1];
00326 gu = d__[1];
00327 eold = 0.f;
00328 emax = 0.f;
00329 e[*n] = 0.f;
00330 i__1 = *n;
00331 for (i__ = 1; i__ <= i__1; ++i__) {
00332 werr[i__] = 0.f;
00333 wgap[i__] = 0.f;
00334 eabs = (r__1 = e[i__], dabs(r__1));
00335 if (eabs >= emax) {
00336 emax = eabs;
00337 }
00338 tmp1 = eabs + eold;
00339 gers[(i__ << 1) - 1] = d__[i__] - tmp1;
00340
00341 r__1 = gl, r__2 = gers[(i__ << 1) - 1];
00342 gl = dmin(r__1,r__2);
00343 gers[i__ * 2] = d__[i__] + tmp1;
00344
00345 r__1 = gu, r__2 = gers[i__ * 2];
00346 gu = dmax(r__1,r__2);
00347 eold = eabs;
00348
00349 }
00350
00351
00352
00353 r__3 = emax;
00354 r__1 = 1.f, r__2 = r__3 * r__3;
00355 *pivmin = safmin * dmax(r__1,r__2);
00356
00357
00358 spdiam = gu - gl;
00359
00360 slarra_(n, &d__[1], &e[1], &e2[1], spltol, &spdiam, nsplit, &isplit[1], &
00361 iinfo);
00362
00363
00364 forceb = FALSE_;
00365
00366
00367 usedqd = irange == 1 && ! forceb;
00368 if (irange == 1 && ! forceb) {
00369
00370 *vl = gl;
00371 *vu = gu;
00372 } else {
00373
00374
00375
00376
00377
00378
00379 slarrd_(range, "B", n, vl, vu, il, iu, &gers[1], &bsrtol, &d__[1], &e[
00380 1], &e2[1], pivmin, nsplit, &isplit[1], &mm, &w[1], &werr[1],
00381 vl, vu, &iblock[1], &indexw[1], &work[1], &iwork[1], &iinfo);
00382 if (iinfo != 0) {
00383 *info = -1;
00384 return 0;
00385 }
00386
00387 i__1 = *n;
00388 for (i__ = mm + 1; i__ <= i__1; ++i__) {
00389 w[i__] = 0.f;
00390 werr[i__] = 0.f;
00391 iblock[i__] = 0;
00392 indexw[i__] = 0;
00393
00394 }
00395 }
00396
00397
00398 ibegin = 1;
00399 wbegin = 1;
00400 i__1 = *nsplit;
00401 for (jblk = 1; jblk <= i__1; ++jblk) {
00402 iend = isplit[jblk];
00403 in = iend - ibegin + 1;
00404
00405 if (in == 1) {
00406 if (irange == 1 || irange == 3 && d__[ibegin] > *vl && d__[ibegin]
00407 <= *vu || irange == 2 && iblock[wbegin] == jblk) {
00408 ++(*m);
00409 w[*m] = d__[ibegin];
00410 werr[*m] = 0.f;
00411
00412
00413 wgap[*m] = 0.f;
00414 iblock[*m] = jblk;
00415 indexw[*m] = 1;
00416 ++wbegin;
00417 }
00418
00419 e[iend] = 0.f;
00420 ibegin = iend + 1;
00421 goto L170;
00422 }
00423
00424
00425
00426
00427 e[iend] = 0.f;
00428
00429
00430 gl = d__[ibegin];
00431 gu = d__[ibegin];
00432 i__2 = iend;
00433 for (i__ = ibegin; i__ <= i__2; ++i__) {
00434
00435 r__1 = gers[(i__ << 1) - 1];
00436 gl = dmin(r__1,gl);
00437
00438 r__1 = gers[i__ * 2];
00439 gu = dmax(r__1,gu);
00440
00441 }
00442 spdiam = gu - gl;
00443 if (! (irange == 1 && ! forceb)) {
00444
00445 mb = 0;
00446 i__2 = mm;
00447 for (i__ = wbegin; i__ <= i__2; ++i__) {
00448 if (iblock[i__] == jblk) {
00449 ++mb;
00450 } else {
00451 goto L21;
00452 }
00453
00454 }
00455 L21:
00456 if (mb == 0) {
00457
00458
00459 e[iend] = 0.f;
00460 ibegin = iend + 1;
00461 goto L170;
00462 } else {
00463
00464 usedqd = (real) mb > in * .5f && ! forceb;
00465 wend = wbegin + mb - 1;
00466
00467
00468
00469 sigma = 0.f;
00470 i__2 = wend - 1;
00471 for (i__ = wbegin; i__ <= i__2; ++i__) {
00472
00473 r__1 = 0.f, r__2 = w[i__ + 1] - werr[i__ + 1] - (w[i__] +
00474 werr[i__]);
00475 wgap[i__] = dmax(r__1,r__2);
00476
00477 }
00478
00479 r__1 = 0.f, r__2 = *vu - sigma - (w[wend] + werr[wend]);
00480 wgap[wend] = dmax(r__1,r__2);
00481
00482 indl = indexw[wbegin];
00483 indu = indexw[wend];
00484 }
00485 }
00486 if (irange == 1 && ! forceb || usedqd) {
00487
00488
00489 slarrk_(&in, &c__1, &gl, &gu, &d__[ibegin], &e2[ibegin], pivmin, &
00490 rtl, &tmp, &tmp1, &iinfo);
00491 if (iinfo != 0) {
00492 *info = -1;
00493 return 0;
00494 }
00495
00496 r__2 = gl, r__3 = tmp - tmp1 - eps * 100.f * (r__1 = tmp - tmp1,
00497 dabs(r__1));
00498 isleft = dmax(r__2,r__3);
00499 slarrk_(&in, &in, &gl, &gu, &d__[ibegin], &e2[ibegin], pivmin, &
00500 rtl, &tmp, &tmp1, &iinfo);
00501 if (iinfo != 0) {
00502 *info = -1;
00503 return 0;
00504 }
00505
00506 r__2 = gu, r__3 = tmp + tmp1 + eps * 100.f * (r__1 = tmp + tmp1,
00507 dabs(r__1));
00508 isrght = dmin(r__2,r__3);
00509
00510 spdiam = isrght - isleft;
00511 } else {
00512
00513
00514
00515 r__2 = gl, r__3 = w[wbegin] - werr[wbegin] - eps * 100.f * (r__1 =
00516 w[wbegin] - werr[wbegin], dabs(r__1));
00517 isleft = dmax(r__2,r__3);
00518
00519 r__2 = gu, r__3 = w[wend] + werr[wend] + eps * 100.f * (r__1 = w[
00520 wend] + werr[wend], dabs(r__1));
00521 isrght = dmin(r__2,r__3);
00522 }
00523
00524
00525
00526
00527
00528
00529
00530
00531 if (irange == 1 && ! forceb) {
00532
00533 usedqd = TRUE_;
00534
00535 indl = 1;
00536 indu = in;
00537
00538 mb = in;
00539 wend = wbegin + mb - 1;
00540
00541 s1 = isleft + spdiam * .25f;
00542 s2 = isrght - spdiam * .25f;
00543 } else {
00544
00545
00546
00547 if (usedqd) {
00548 s1 = isleft + spdiam * .25f;
00549 s2 = isrght - spdiam * .25f;
00550 } else {
00551 tmp = dmin(isrght,*vu) - dmax(isleft,*vl);
00552 s1 = dmax(isleft,*vl) + tmp * .25f;
00553 s2 = dmin(isrght,*vu) - tmp * .25f;
00554 }
00555 }
00556
00557 if (mb > 1) {
00558 slarrc_("T", &in, &s1, &s2, &d__[ibegin], &e[ibegin], pivmin, &
00559 cnt, &cnt1, &cnt2, &iinfo);
00560 }
00561 if (mb == 1) {
00562 sigma = gl;
00563 sgndef = 1.f;
00564 } else if (cnt1 - indl >= indu - cnt2) {
00565 if (irange == 1 && ! forceb) {
00566 sigma = dmax(isleft,gl);
00567 } else if (usedqd) {
00568
00569
00570 sigma = isleft;
00571 } else {
00572
00573
00574 sigma = dmax(isleft,*vl);
00575 }
00576 sgndef = 1.f;
00577 } else {
00578 if (irange == 1 && ! forceb) {
00579 sigma = dmin(isrght,gu);
00580 } else if (usedqd) {
00581
00582
00583 sigma = isrght;
00584 } else {
00585
00586
00587 sigma = dmin(isrght,*vu);
00588 }
00589 sgndef = -1.f;
00590 }
00591
00592
00593
00594
00595
00596 if (usedqd) {
00597
00598
00599 tau = spdiam * eps * *n + *pivmin * 2.f;
00600 } else {
00601 if (mb > 1) {
00602 clwdth = w[wend] + werr[wend] - w[wbegin] - werr[wbegin];
00603 avgap = (r__1 = clwdth / (real) (wend - wbegin), dabs(r__1));
00604 if (sgndef == 1.f) {
00605
00606 r__1 = wgap[wbegin];
00607 tau = dmax(r__1,avgap) * .5f;
00608
00609 r__1 = tau, r__2 = werr[wbegin];
00610 tau = dmax(r__1,r__2);
00611 } else {
00612
00613 r__1 = wgap[wend - 1];
00614 tau = dmax(r__1,avgap) * .5f;
00615
00616 r__1 = tau, r__2 = werr[wend];
00617 tau = dmax(r__1,r__2);
00618 }
00619 } else {
00620 tau = werr[wbegin];
00621 }
00622 }
00623
00624 for (idum = 1; idum <= 6; ++idum) {
00625
00626
00627
00628 dpivot = d__[ibegin] - sigma;
00629 work[1] = dpivot;
00630 dmax__ = dabs(work[1]);
00631 j = ibegin;
00632 i__2 = in - 1;
00633 for (i__ = 1; i__ <= i__2; ++i__) {
00634 work[(in << 1) + i__] = 1.f / work[i__];
00635 tmp = e[j] * work[(in << 1) + i__];
00636 work[in + i__] = tmp;
00637 dpivot = d__[j + 1] - sigma - tmp * e[j];
00638 work[i__ + 1] = dpivot;
00639
00640 r__1 = dmax__, r__2 = dabs(dpivot);
00641 dmax__ = dmax(r__1,r__2);
00642 ++j;
00643
00644 }
00645
00646 if (dmax__ > spdiam * 64.f) {
00647 norep = TRUE_;
00648 } else {
00649 norep = FALSE_;
00650 }
00651 if (usedqd && ! norep) {
00652
00653
00654 i__2 = in;
00655 for (i__ = 1; i__ <= i__2; ++i__) {
00656 tmp = sgndef * work[i__];
00657 if (tmp < 0.f) {
00658 norep = TRUE_;
00659 }
00660
00661 }
00662 }
00663 if (norep) {
00664
00665
00666
00667 if (idum == 5) {
00668 if (sgndef == 1.f) {
00669
00670 sigma = gl - spdiam * 2.f * eps * *n - *pivmin * 4.f;
00671 } else {
00672 sigma = gu + spdiam * 2.f * eps * *n + *pivmin * 4.f;
00673 }
00674 } else {
00675 sigma -= sgndef * tau;
00676 tau *= 2.f;
00677 }
00678 } else {
00679
00680 goto L83;
00681 }
00682
00683 }
00684
00685
00686 *info = 2;
00687 return 0;
00688 L83:
00689
00690
00691
00692 e[iend] = sigma;
00693
00694 scopy_(&in, &work[1], &c__1, &d__[ibegin], &c__1);
00695 i__2 = in - 1;
00696 scopy_(&i__2, &work[in + 1], &c__1, &e[ibegin], &c__1);
00697 if (mb > 1) {
00698
00699
00700
00701
00702
00703 for (i__ = 1; i__ <= 4; ++i__) {
00704 iseed[i__ - 1] = 1;
00705
00706 }
00707 i__2 = (in << 1) - 1;
00708 slarnv_(&c__2, iseed, &i__2, &work[1]);
00709 i__2 = in - 1;
00710 for (i__ = 1; i__ <= i__2; ++i__) {
00711 d__[ibegin + i__ - 1] *= eps * 4.f * work[i__] + 1.f;
00712 e[ibegin + i__ - 1] *= eps * 4.f * work[in + i__] + 1.f;
00713
00714 }
00715 d__[iend] *= eps * 4.f * work[in] + 1.f;
00716
00717 }
00718
00719
00720
00721
00722
00723
00724 if (! usedqd) {
00725
00726
00727
00728
00729
00730 i__2 = wend;
00731 for (j = wbegin; j <= i__2; ++j) {
00732 w[j] -= sigma;
00733 werr[j] += (r__1 = w[j], dabs(r__1)) * eps;
00734
00735 }
00736
00737
00738 i__2 = iend - 1;
00739 for (i__ = ibegin; i__ <= i__2; ++i__) {
00740
00741 r__1 = e[i__];
00742 work[i__] = d__[i__] * (r__1 * r__1);
00743
00744 }
00745
00746 i__2 = indl - 1;
00747 slarrb_(&in, &d__[ibegin], &work[ibegin], &indl, &indu, rtol1,
00748 rtol2, &i__2, &w[wbegin], &wgap[wbegin], &werr[wbegin], &
00749 work[(*n << 1) + 1], &iwork[1], pivmin, &spdiam, &in, &
00750 iinfo);
00751 if (iinfo != 0) {
00752 *info = -4;
00753 return 0;
00754 }
00755
00756
00757
00758 r__1 = 0.f, r__2 = *vu - sigma - (w[wend] + werr[wend]);
00759 wgap[wend] = dmax(r__1,r__2);
00760 i__2 = indu;
00761 for (i__ = indl; i__ <= i__2; ++i__) {
00762 ++(*m);
00763 iblock[*m] = jblk;
00764 indexw[*m] = i__;
00765
00766 }
00767 } else {
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779 rtol = log((real) in) * 4.f * eps;
00780 j = ibegin;
00781 i__2 = in - 1;
00782 for (i__ = 1; i__ <= i__2; ++i__) {
00783 work[(i__ << 1) - 1] = (r__1 = d__[j], dabs(r__1));
00784 work[i__ * 2] = e[j] * e[j] * work[(i__ << 1) - 1];
00785 ++j;
00786
00787 }
00788 work[(in << 1) - 1] = (r__1 = d__[iend], dabs(r__1));
00789 work[in * 2] = 0.f;
00790 slasq2_(&in, &work[1], &iinfo);
00791 if (iinfo != 0) {
00792
00793
00794
00795 *info = -5;
00796 return 0;
00797 } else {
00798
00799 i__2 = in;
00800 for (i__ = 1; i__ <= i__2; ++i__) {
00801 if (work[i__] < 0.f) {
00802 *info = -6;
00803 return 0;
00804 }
00805
00806 }
00807 }
00808 if (sgndef > 0.f) {
00809 i__2 = indu;
00810 for (i__ = indl; i__ <= i__2; ++i__) {
00811 ++(*m);
00812 w[*m] = work[in - i__ + 1];
00813 iblock[*m] = jblk;
00814 indexw[*m] = i__;
00815
00816 }
00817 } else {
00818 i__2 = indu;
00819 for (i__ = indl; i__ <= i__2; ++i__) {
00820 ++(*m);
00821 w[*m] = -work[i__];
00822 iblock[*m] = jblk;
00823 indexw[*m] = i__;
00824
00825 }
00826 }
00827 i__2 = *m;
00828 for (i__ = *m - mb + 1; i__ <= i__2; ++i__) {
00829
00830 werr[i__] = rtol * (r__1 = w[i__], dabs(r__1));
00831
00832 }
00833 i__2 = *m - 1;
00834 for (i__ = *m - mb + 1; i__ <= i__2; ++i__) {
00835
00836
00837 r__1 = 0.f, r__2 = w[i__ + 1] - werr[i__ + 1] - (w[i__] +
00838 werr[i__]);
00839 wgap[i__] = dmax(r__1,r__2);
00840
00841 }
00842
00843 r__1 = 0.f, r__2 = *vu - sigma - (w[*m] + werr[*m]);
00844 wgap[*m] = dmax(r__1,r__2);
00845 }
00846
00847 ibegin = iend + 1;
00848 wbegin = wend + 1;
00849 L170:
00850 ;
00851 }
00852
00853 return 0;
00854
00855
00856
00857 }