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
00020 int slarrf_(integer *n, real *d__, real *l, real *ld,
00021 integer *clstrt, integer *clend, real *w, real *wgap, real *werr,
00022 real *spdiam, real *clgapl, real *clgapr, real *pivmin, real *sigma,
00023 real *dplus, real *lplus, real *work, integer *info)
00024 {
00025
00026 integer i__1;
00027 real r__1, r__2, r__3;
00028
00029
00030 double sqrt(doublereal);
00031
00032
00033 integer i__;
00034 real s, bestshift, smlgrowth, eps, tmp, max1, max2, rrr1, rrr2, znm2,
00035 growthbound, fail, fact, oldp;
00036 integer indx;
00037 real prod;
00038 integer ktry;
00039 real fail2, avgap, ldmax, rdmax;
00040 integer shift;
00041 extern int scopy_(integer *, real *, integer *, real *,
00042 integer *);
00043 logical dorrr1;
00044 real ldelta;
00045 extern doublereal slamch_(char *);
00046 logical nofail;
00047 real mingap, lsigma, rdelta;
00048 logical forcer;
00049 real rsigma, clwdth;
00050 extern logical sisnan_(real *);
00051 logical sawnan1, sawnan2, tryrrr1;
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
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 --work;
00155 --lplus;
00156 --dplus;
00157 --werr;
00158 --wgap;
00159 --w;
00160 --ld;
00161 --l;
00162 --d__;
00163
00164
00165 *info = 0;
00166 fact = 2.f;
00167 eps = slamch_("Precision");
00168 shift = 0;
00169 forcer = FALSE_;
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181 nofail = TRUE_;
00182
00183
00184 clwdth = (r__1 = w[*clend] - w[*clstrt], dabs(r__1)) + werr[*clend] +
00185 werr[*clstrt];
00186 avgap = clwdth / (real) (*clend - *clstrt);
00187 mingap = dmin(*clgapl,*clgapr);
00188
00189
00190 r__1 = w[*clstrt], r__2 = w[*clend];
00191 lsigma = dmin(r__1,r__2) - werr[*clstrt];
00192
00193 r__1 = w[*clstrt], r__2 = w[*clend];
00194 rsigma = dmax(r__1,r__2) + werr[*clend];
00195
00196 lsigma -= dabs(lsigma) * 2.f * eps;
00197 rsigma += dabs(rsigma) * 2.f * eps;
00198
00199 ldmax = mingap * .25f + *pivmin * 2.f;
00200 rdmax = mingap * .25f + *pivmin * 2.f;
00201
00202 r__1 = avgap, r__2 = wgap[*clstrt];
00203 ldelta = dmax(r__1,r__2) / fact;
00204
00205 r__1 = avgap, r__2 = wgap[*clend - 1];
00206 rdelta = dmax(r__1,r__2) / fact;
00207
00208
00209
00210 s = slamch_("S");
00211 smlgrowth = 1.f / s;
00212 fail = (real) (*n - 1) * mingap / (*spdiam * eps);
00213 fail2 = (real) (*n - 1) * mingap / (*spdiam * sqrt(eps));
00214 bestshift = lsigma;
00215
00216
00217 ktry = 0;
00218 growthbound = *spdiam * 8.f;
00219 L5:
00220 sawnan1 = FALSE_;
00221 sawnan2 = FALSE_;
00222
00223 ldelta = dmin(ldmax,ldelta);
00224 rdelta = dmin(rdmax,rdelta);
00225
00226
00227
00228 s = -lsigma;
00229 dplus[1] = d__[1] + s;
00230 if (dabs(dplus[1]) < *pivmin) {
00231 dplus[1] = -(*pivmin);
00232
00233
00234 sawnan1 = TRUE_;
00235 }
00236 max1 = dabs(dplus[1]);
00237 i__1 = *n - 1;
00238 for (i__ = 1; i__ <= i__1; ++i__) {
00239 lplus[i__] = ld[i__] / dplus[i__];
00240 s = s * lplus[i__] * l[i__] - lsigma;
00241 dplus[i__ + 1] = d__[i__ + 1] + s;
00242 if ((r__1 = dplus[i__ + 1], dabs(r__1)) < *pivmin) {
00243 dplus[i__ + 1] = -(*pivmin);
00244
00245
00246 sawnan1 = TRUE_;
00247 }
00248
00249 r__2 = max1, r__3 = (r__1 = dplus[i__ + 1], dabs(r__1));
00250 max1 = dmax(r__2,r__3);
00251
00252 }
00253 sawnan1 = sawnan1 || sisnan_(&max1);
00254 if (forcer || max1 <= growthbound && ! sawnan1) {
00255 *sigma = lsigma;
00256 shift = 1;
00257 goto L100;
00258 }
00259
00260 s = -rsigma;
00261 work[1] = d__[1] + s;
00262 if (dabs(work[1]) < *pivmin) {
00263 work[1] = -(*pivmin);
00264
00265
00266 sawnan2 = TRUE_;
00267 }
00268 max2 = dabs(work[1]);
00269 i__1 = *n - 1;
00270 for (i__ = 1; i__ <= i__1; ++i__) {
00271 work[*n + i__] = ld[i__] / work[i__];
00272 s = s * work[*n + i__] * l[i__] - rsigma;
00273 work[i__ + 1] = d__[i__ + 1] + s;
00274 if ((r__1 = work[i__ + 1], dabs(r__1)) < *pivmin) {
00275 work[i__ + 1] = -(*pivmin);
00276
00277
00278 sawnan2 = TRUE_;
00279 }
00280
00281 r__2 = max2, r__3 = (r__1 = work[i__ + 1], dabs(r__1));
00282 max2 = dmax(r__2,r__3);
00283
00284 }
00285 sawnan2 = sawnan2 || sisnan_(&max2);
00286 if (forcer || max2 <= growthbound && ! sawnan2) {
00287 *sigma = rsigma;
00288 shift = 2;
00289 goto L100;
00290 }
00291
00292
00293 if (sawnan1 && sawnan2) {
00294
00295 goto L50;
00296 } else {
00297 if (! sawnan1) {
00298 indx = 1;
00299 if (max1 <= smlgrowth) {
00300 smlgrowth = max1;
00301 bestshift = lsigma;
00302 }
00303 }
00304 if (! sawnan2) {
00305 if (sawnan1 || max2 <= max1) {
00306 indx = 2;
00307 }
00308 if (max2 <= smlgrowth) {
00309 smlgrowth = max2;
00310 bestshift = rsigma;
00311 }
00312 }
00313 }
00314
00315
00316
00317
00318
00319 if (clwdth < mingap / 128.f && dmin(max1,max2) < fail2 && ! sawnan1 && !
00320 sawnan2) {
00321 dorrr1 = TRUE_;
00322 } else {
00323 dorrr1 = FALSE_;
00324 }
00325 tryrrr1 = TRUE_;
00326 if (tryrrr1 && dorrr1) {
00327 if (indx == 1) {
00328 tmp = (r__1 = dplus[*n], dabs(r__1));
00329 znm2 = 1.f;
00330 prod = 1.f;
00331 oldp = 1.f;
00332 for (i__ = *n - 1; i__ >= 1; --i__) {
00333 if (prod <= eps) {
00334 prod = dplus[i__ + 1] * work[*n + i__ + 1] / (dplus[i__] *
00335 work[*n + i__]) * oldp;
00336 } else {
00337 prod *= (r__1 = work[*n + i__], dabs(r__1));
00338 }
00339 oldp = prod;
00340
00341 r__1 = prod;
00342 znm2 += r__1 * r__1;
00343
00344 r__2 = tmp, r__3 = (r__1 = dplus[i__] * prod, dabs(r__1));
00345 tmp = dmax(r__2,r__3);
00346
00347 }
00348 rrr1 = tmp / (*spdiam * sqrt(znm2));
00349 if (rrr1 <= 8.f) {
00350 *sigma = lsigma;
00351 shift = 1;
00352 goto L100;
00353 }
00354 } else if (indx == 2) {
00355 tmp = (r__1 = work[*n], dabs(r__1));
00356 znm2 = 1.f;
00357 prod = 1.f;
00358 oldp = 1.f;
00359 for (i__ = *n - 1; i__ >= 1; --i__) {
00360 if (prod <= eps) {
00361 prod = work[i__ + 1] * lplus[i__ + 1] / (work[i__] *
00362 lplus[i__]) * oldp;
00363 } else {
00364 prod *= (r__1 = lplus[i__], dabs(r__1));
00365 }
00366 oldp = prod;
00367
00368 r__1 = prod;
00369 znm2 += r__1 * r__1;
00370
00371 r__2 = tmp, r__3 = (r__1 = work[i__] * prod, dabs(r__1));
00372 tmp = dmax(r__2,r__3);
00373
00374 }
00375 rrr2 = tmp / (*spdiam * sqrt(znm2));
00376 if (rrr2 <= 8.f) {
00377 *sigma = rsigma;
00378 shift = 2;
00379 goto L100;
00380 }
00381 }
00382 }
00383 L50:
00384 if (ktry < 1) {
00385
00386
00387
00388 r__1 = lsigma - ldelta, r__2 = lsigma - ldmax;
00389 lsigma = dmax(r__1,r__2);
00390
00391 r__1 = rsigma + rdelta, r__2 = rsigma + rdmax;
00392 rsigma = dmin(r__1,r__2);
00393 ldelta *= 2.f;
00394 rdelta *= 2.f;
00395 ++ktry;
00396 goto L5;
00397 } else {
00398
00399
00400 if (smlgrowth < fail || nofail) {
00401 lsigma = bestshift;
00402 rsigma = bestshift;
00403 forcer = TRUE_;
00404 goto L5;
00405 } else {
00406 *info = 1;
00407 return 0;
00408 }
00409 }
00410 L100:
00411 if (shift == 1) {
00412 } else if (shift == 2) {
00413
00414 scopy_(n, &work[1], &c__1, &dplus[1], &c__1);
00415 i__1 = *n - 1;
00416 scopy_(&i__1, &work[*n + 1], &c__1, &lplus[1], &c__1);
00417 }
00418 return 0;
00419
00420
00421
00422 }