00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "f2c.h"
00014 #include "blaswrap.h"
00015
00016 int dlaed6_(integer *kniter, logical *orgati, doublereal *
00017 rho, doublereal *d__, doublereal *z__, doublereal *finit, doublereal *
00018 tau, integer *info)
00019 {
00020
00021 integer i__1;
00022 doublereal d__1, d__2, d__3, d__4;
00023
00024
00025 double sqrt(doublereal), log(doublereal), pow_di(doublereal *, integer *);
00026
00027
00028 doublereal a, b, c__, f;
00029 integer i__;
00030 doublereal fc, df, ddf, lbd, eta, ubd, eps, base;
00031 integer iter;
00032 doublereal temp, temp1, temp2, temp3, temp4;
00033 logical scale;
00034 integer niter;
00035 doublereal small1, small2, sminv1, sminv2;
00036 extern doublereal dlamch_(char *);
00037 doublereal dscale[3], sclfac, zscale[3], erretm, sclinv;
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
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 --z__;
00128 --d__;
00129
00130
00131 *info = 0;
00132
00133 if (*orgati) {
00134 lbd = d__[2];
00135 ubd = d__[3];
00136 } else {
00137 lbd = d__[1];
00138 ubd = d__[2];
00139 }
00140 if (*finit < 0.) {
00141 lbd = 0.;
00142 } else {
00143 ubd = 0.;
00144 }
00145
00146 niter = 1;
00147 *tau = 0.;
00148 if (*kniter == 2) {
00149 if (*orgati) {
00150 temp = (d__[3] - d__[2]) / 2.;
00151 c__ = *rho + z__[1] / (d__[1] - d__[2] - temp);
00152 a = c__ * (d__[2] + d__[3]) + z__[2] + z__[3];
00153 b = c__ * d__[2] * d__[3] + z__[2] * d__[3] + z__[3] * d__[2];
00154 } else {
00155 temp = (d__[1] - d__[2]) / 2.;
00156 c__ = *rho + z__[3] / (d__[3] - d__[2] - temp);
00157 a = c__ * (d__[1] + d__[2]) + z__[1] + z__[2];
00158 b = c__ * d__[1] * d__[2] + z__[1] * d__[2] + z__[2] * d__[1];
00159 }
00160
00161 d__1 = abs(a), d__2 = abs(b), d__1 = max(d__1,d__2), d__2 = abs(c__);
00162 temp = max(d__1,d__2);
00163 a /= temp;
00164 b /= temp;
00165 c__ /= temp;
00166 if (c__ == 0.) {
00167 *tau = b / a;
00168 } else if (a <= 0.) {
00169 *tau = (a - sqrt((d__1 = a * a - b * 4. * c__, abs(d__1)))) / (
00170 c__ * 2.);
00171 } else {
00172 *tau = b * 2. / (a + sqrt((d__1 = a * a - b * 4. * c__, abs(d__1))
00173 ));
00174 }
00175 if (*tau < lbd || *tau > ubd) {
00176 *tau = (lbd + ubd) / 2.;
00177 }
00178 if (d__[1] == *tau || d__[2] == *tau || d__[3] == *tau) {
00179 *tau = 0.;
00180 } else {
00181 temp = *finit + *tau * z__[1] / (d__[1] * (d__[1] - *tau)) + *tau
00182 * z__[2] / (d__[2] * (d__[2] - *tau)) + *tau * z__[3] / (
00183 d__[3] * (d__[3] - *tau));
00184 if (temp <= 0.) {
00185 lbd = *tau;
00186 } else {
00187 ubd = *tau;
00188 }
00189 if (abs(*finit) <= abs(temp)) {
00190 *tau = 0.;
00191 }
00192 }
00193 }
00194
00195
00196
00197
00198
00199
00200
00201 eps = dlamch_("Epsilon");
00202 base = dlamch_("Base");
00203 i__1 = (integer) (log(dlamch_("SafMin")) / log(base) / 3.);
00204 small1 = pow_di(&base, &i__1);
00205 sminv1 = 1. / small1;
00206 small2 = small1 * small1;
00207 sminv2 = sminv1 * sminv1;
00208
00209
00210
00211
00212 if (*orgati) {
00213
00214 d__3 = (d__1 = d__[2] - *tau, abs(d__1)), d__4 = (d__2 = d__[3] - *
00215 tau, abs(d__2));
00216 temp = min(d__3,d__4);
00217 } else {
00218
00219 d__3 = (d__1 = d__[1] - *tau, abs(d__1)), d__4 = (d__2 = d__[2] - *
00220 tau, abs(d__2));
00221 temp = min(d__3,d__4);
00222 }
00223 scale = FALSE_;
00224 if (temp <= small1) {
00225 scale = TRUE_;
00226 if (temp <= small2) {
00227
00228
00229
00230 sclfac = sminv2;
00231 sclinv = small2;
00232 } else {
00233
00234
00235
00236 sclfac = sminv1;
00237 sclinv = small1;
00238 }
00239
00240
00241
00242 for (i__ = 1; i__ <= 3; ++i__) {
00243 dscale[i__ - 1] = d__[i__] * sclfac;
00244 zscale[i__ - 1] = z__[i__] * sclfac;
00245
00246 }
00247 *tau *= sclfac;
00248 lbd *= sclfac;
00249 ubd *= sclfac;
00250 } else {
00251
00252
00253
00254 for (i__ = 1; i__ <= 3; ++i__) {
00255 dscale[i__ - 1] = d__[i__];
00256 zscale[i__ - 1] = z__[i__];
00257
00258 }
00259 }
00260
00261 fc = 0.;
00262 df = 0.;
00263 ddf = 0.;
00264 for (i__ = 1; i__ <= 3; ++i__) {
00265 temp = 1. / (dscale[i__ - 1] - *tau);
00266 temp1 = zscale[i__ - 1] * temp;
00267 temp2 = temp1 * temp;
00268 temp3 = temp2 * temp;
00269 fc += temp1 / dscale[i__ - 1];
00270 df += temp2;
00271 ddf += temp3;
00272
00273 }
00274 f = *finit + *tau * fc;
00275
00276 if (abs(f) <= 0.) {
00277 goto L60;
00278 }
00279 if (f <= 0.) {
00280 lbd = *tau;
00281 } else {
00282 ubd = *tau;
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296 iter = niter + 1;
00297
00298 for (niter = iter; niter <= 40; ++niter) {
00299
00300 if (*orgati) {
00301 temp1 = dscale[1] - *tau;
00302 temp2 = dscale[2] - *tau;
00303 } else {
00304 temp1 = dscale[0] - *tau;
00305 temp2 = dscale[1] - *tau;
00306 }
00307 a = (temp1 + temp2) * f - temp1 * temp2 * df;
00308 b = temp1 * temp2 * f;
00309 c__ = f - (temp1 + temp2) * df + temp1 * temp2 * ddf;
00310
00311 d__1 = abs(a), d__2 = abs(b), d__1 = max(d__1,d__2), d__2 = abs(c__);
00312 temp = max(d__1,d__2);
00313 a /= temp;
00314 b /= temp;
00315 c__ /= temp;
00316 if (c__ == 0.) {
00317 eta = b / a;
00318 } else if (a <= 0.) {
00319 eta = (a - sqrt((d__1 = a * a - b * 4. * c__, abs(d__1)))) / (c__
00320 * 2.);
00321 } else {
00322 eta = b * 2. / (a + sqrt((d__1 = a * a - b * 4. * c__, abs(d__1)))
00323 );
00324 }
00325 if (f * eta >= 0.) {
00326 eta = -f / df;
00327 }
00328
00329 *tau += eta;
00330 if (*tau < lbd || *tau > ubd) {
00331 *tau = (lbd + ubd) / 2.;
00332 }
00333
00334 fc = 0.;
00335 erretm = 0.;
00336 df = 0.;
00337 ddf = 0.;
00338 for (i__ = 1; i__ <= 3; ++i__) {
00339 temp = 1. / (dscale[i__ - 1] - *tau);
00340 temp1 = zscale[i__ - 1] * temp;
00341 temp2 = temp1 * temp;
00342 temp3 = temp2 * temp;
00343 temp4 = temp1 / dscale[i__ - 1];
00344 fc += temp4;
00345 erretm += abs(temp4);
00346 df += temp2;
00347 ddf += temp3;
00348
00349 }
00350 f = *finit + *tau * fc;
00351 erretm = (abs(*finit) + abs(*tau) * erretm) * 8. + abs(*tau) * df;
00352 if (abs(f) <= eps * erretm) {
00353 goto L60;
00354 }
00355 if (f <= 0.) {
00356 lbd = *tau;
00357 } else {
00358 ubd = *tau;
00359 }
00360
00361 }
00362 *info = 1;
00363 L60:
00364
00365
00366
00367 if (scale) {
00368 *tau *= sclinv;
00369 }
00370 return 0;
00371
00372
00373
00374 }