dlaed4.c
Go to the documentation of this file.
00001 /* dlaed4.f -- translated by f2c (version 20061008).
00002    You must link the resulting object file with libf2c:
00003         on Microsoft Windows system, link with libf2c.lib;
00004         on Linux or Unix systems, link with .../path/to/libf2c.a -lm
00005         or, if you install libf2c.a in a standard place, with -lf2c -lm
00006         -- in that order, at the end of the command line, as in
00007                 cc *.o -lf2c -lm
00008         Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
00009 
00010                 http://www.netlib.org/f2c/libf2c.zip
00011 */
00012 
00013 #include "f2c.h"
00014 #include "blaswrap.h"
00015 
00016 /* Subroutine */ int dlaed4_(integer *n, integer *i__, doublereal *d__, 
00017         doublereal *z__, doublereal *delta, doublereal *rho, doublereal *dlam, 
00018          integer *info)
00019 {
00020     /* System generated locals */
00021     integer i__1;
00022     doublereal d__1;
00023 
00024     /* Builtin functions */
00025     double sqrt(doublereal);
00026 
00027     /* Local variables */
00028     doublereal a, b, c__;
00029     integer j;
00030     doublereal w;
00031     integer ii;
00032     doublereal dw, zz[3];
00033     integer ip1;
00034     doublereal del, eta, phi, eps, tau, psi;
00035     integer iim1, iip1;
00036     doublereal dphi, dpsi;
00037     integer iter;
00038     doublereal temp, prew, temp1, dltlb, dltub, midpt;
00039     integer niter;
00040     logical swtch;
00041     extern /* Subroutine */ int dlaed5_(integer *, doublereal *, doublereal *, 
00042              doublereal *, doublereal *, doublereal *), dlaed6_(integer *, 
00043             logical *, doublereal *, doublereal *, doublereal *, doublereal *, 
00044              doublereal *, integer *);
00045     logical swtch3;
00046     extern doublereal dlamch_(char *);
00047     logical orgati;
00048     doublereal erretm, rhoinv;
00049 
00050 
00051 /*  -- LAPACK routine (version 3.2) -- */
00052 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00053 /*     November 2006 */
00054 
00055 /*     .. Scalar Arguments .. */
00056 /*     .. */
00057 /*     .. Array Arguments .. */
00058 /*     .. */
00059 
00060 /*  Purpose */
00061 /*  ======= */
00062 
00063 /*  This subroutine computes the I-th updated eigenvalue of a symmetric */
00064 /*  rank-one modification to a diagonal matrix whose elements are */
00065 /*  given in the array d, and that */
00066 
00067 /*             D(i) < D(j)  for  i < j */
00068 
00069 /*  and that RHO > 0.  This is arranged by the calling routine, and is */
00070 /*  no loss in generality.  The rank-one modified system is thus */
00071 
00072 /*             diag( D )  +  RHO *  Z * Z_transpose. */
00073 
00074 /*  where we assume the Euclidean norm of Z is 1. */
00075 
00076 /*  The method consists of approximating the rational functions in the */
00077 /*  secular equation by simpler interpolating rational functions. */
00078 
00079 /*  Arguments */
00080 /*  ========= */
00081 
00082 /*  N      (input) INTEGER */
00083 /*         The length of all arrays. */
00084 
00085 /*  I      (input) INTEGER */
00086 /*         The index of the eigenvalue to be computed.  1 <= I <= N. */
00087 
00088 /*  D      (input) DOUBLE PRECISION array, dimension (N) */
00089 /*         The original eigenvalues.  It is assumed that they are in */
00090 /*         order, D(I) < D(J)  for I < J. */
00091 
00092 /*  Z      (input) DOUBLE PRECISION array, dimension (N) */
00093 /*         The components of the updating vector. */
00094 
00095 /*  DELTA  (output) DOUBLE PRECISION array, dimension (N) */
00096 /*         If N .GT. 2, DELTA contains (D(j) - lambda_I) in its  j-th */
00097 /*         component.  If N = 1, then DELTA(1) = 1. If N = 2, see DLAED5 */
00098 /*         for detail. The vector DELTA contains the information necessary */
00099 /*         to construct the eigenvectors by DLAED3 and DLAED9. */
00100 
00101 /*  RHO    (input) DOUBLE PRECISION */
00102 /*         The scalar in the symmetric updating formula. */
00103 
00104 /*  DLAM   (output) DOUBLE PRECISION */
00105 /*         The computed lambda_I, the I-th updated eigenvalue. */
00106 
00107 /*  INFO   (output) INTEGER */
00108 /*         = 0:  successful exit */
00109 /*         > 0:  if INFO = 1, the updating process failed. */
00110 
00111 /*  Internal Parameters */
00112 /*  =================== */
00113 
00114 /*  Logical variable ORGATI (origin-at-i?) is used for distinguishing */
00115 /*  whether D(i) or D(i+1) is treated as the origin. */
00116 
00117 /*            ORGATI = .true.    origin at i */
00118 /*            ORGATI = .false.   origin at i+1 */
00119 
00120 /*   Logical variable SWTCH3 (switch-for-3-poles?) is for noting */
00121 /*   if we are working with THREE poles! */
00122 
00123 /*   MAXIT is the maximum number of iterations allowed for each */
00124 /*   eigenvalue. */
00125 
00126 /*  Further Details */
00127 /*  =============== */
00128 
00129 /*  Based on contributions by */
00130 /*     Ren-Cang Li, Computer Science Division, University of California */
00131 /*     at Berkeley, USA */
00132 
00133 /*  ===================================================================== */
00134 
00135 /*     .. Parameters .. */
00136 /*     .. */
00137 /*     .. Local Scalars .. */
00138 /*     .. */
00139 /*     .. Local Arrays .. */
00140 /*     .. */
00141 /*     .. External Functions .. */
00142 /*     .. */
00143 /*     .. External Subroutines .. */
00144 /*     .. */
00145 /*     .. Intrinsic Functions .. */
00146 /*     .. */
00147 /*     .. Executable Statements .. */
00148 
00149 /*     Since this routine is called in an inner loop, we do no argument */
00150 /*     checking. */
00151 
00152 /*     Quick return for N=1 and 2. */
00153 
00154     /* Parameter adjustments */
00155     --delta;
00156     --z__;
00157     --d__;
00158 
00159     /* Function Body */
00160     *info = 0;
00161     if (*n == 1) {
00162 
00163 /*         Presumably, I=1 upon entry */
00164 
00165         *dlam = d__[1] + *rho * z__[1] * z__[1];
00166         delta[1] = 1.;
00167         return 0;
00168     }
00169     if (*n == 2) {
00170         dlaed5_(i__, &d__[1], &z__[1], &delta[1], rho, dlam);
00171         return 0;
00172     }
00173 
00174 /*     Compute machine epsilon */
00175 
00176     eps = dlamch_("Epsilon");
00177     rhoinv = 1. / *rho;
00178 
00179 /*     The case I = N */
00180 
00181     if (*i__ == *n) {
00182 
00183 /*        Initialize some basic variables */
00184 
00185         ii = *n - 1;
00186         niter = 1;
00187 
00188 /*        Calculate initial guess */
00189 
00190         midpt = *rho / 2.;
00191 
00192 /*        If ||Z||_2 is not one, then TEMP should be set to */
00193 /*        RHO * ||Z||_2^2 / TWO */
00194 
00195         i__1 = *n;
00196         for (j = 1; j <= i__1; ++j) {
00197             delta[j] = d__[j] - d__[*i__] - midpt;
00198 /* L10: */
00199         }
00200 
00201         psi = 0.;
00202         i__1 = *n - 2;
00203         for (j = 1; j <= i__1; ++j) {
00204             psi += z__[j] * z__[j] / delta[j];
00205 /* L20: */
00206         }
00207 
00208         c__ = rhoinv + psi;
00209         w = c__ + z__[ii] * z__[ii] / delta[ii] + z__[*n] * z__[*n] / delta[*
00210                 n];
00211 
00212         if (w <= 0.) {
00213             temp = z__[*n - 1] * z__[*n - 1] / (d__[*n] - d__[*n - 1] + *rho) 
00214                     + z__[*n] * z__[*n] / *rho;
00215             if (c__ <= temp) {
00216                 tau = *rho;
00217             } else {
00218                 del = d__[*n] - d__[*n - 1];
00219                 a = -c__ * del + z__[*n - 1] * z__[*n - 1] + z__[*n] * z__[*n]
00220                         ;
00221                 b = z__[*n] * z__[*n] * del;
00222                 if (a < 0.) {
00223                     tau = b * 2. / (sqrt(a * a + b * 4. * c__) - a);
00224                 } else {
00225                     tau = (a + sqrt(a * a + b * 4. * c__)) / (c__ * 2.);
00226                 }
00227             }
00228 
00229 /*           It can be proved that */
00230 /*               D(N)+RHO/2 <= LAMBDA(N) < D(N)+TAU <= D(N)+RHO */
00231 
00232             dltlb = midpt;
00233             dltub = *rho;
00234         } else {
00235             del = d__[*n] - d__[*n - 1];
00236             a = -c__ * del + z__[*n - 1] * z__[*n - 1] + z__[*n] * z__[*n];
00237             b = z__[*n] * z__[*n] * del;
00238             if (a < 0.) {
00239                 tau = b * 2. / (sqrt(a * a + b * 4. * c__) - a);
00240             } else {
00241                 tau = (a + sqrt(a * a + b * 4. * c__)) / (c__ * 2.);
00242             }
00243 
00244 /*           It can be proved that */
00245 /*               D(N) < D(N)+TAU < LAMBDA(N) < D(N)+RHO/2 */
00246 
00247             dltlb = 0.;
00248             dltub = midpt;
00249         }
00250 
00251         i__1 = *n;
00252         for (j = 1; j <= i__1; ++j) {
00253             delta[j] = d__[j] - d__[*i__] - tau;
00254 /* L30: */
00255         }
00256 
00257 /*        Evaluate PSI and the derivative DPSI */
00258 
00259         dpsi = 0.;
00260         psi = 0.;
00261         erretm = 0.;
00262         i__1 = ii;
00263         for (j = 1; j <= i__1; ++j) {
00264             temp = z__[j] / delta[j];
00265             psi += z__[j] * temp;
00266             dpsi += temp * temp;
00267             erretm += psi;
00268 /* L40: */
00269         }
00270         erretm = abs(erretm);
00271 
00272 /*        Evaluate PHI and the derivative DPHI */
00273 
00274         temp = z__[*n] / delta[*n];
00275         phi = z__[*n] * temp;
00276         dphi = temp * temp;
00277         erretm = (-phi - psi) * 8. + erretm - phi + rhoinv + abs(tau) * (dpsi 
00278                 + dphi);
00279 
00280         w = rhoinv + phi + psi;
00281 
00282 /*        Test for convergence */
00283 
00284         if (abs(w) <= eps * erretm) {
00285             *dlam = d__[*i__] + tau;
00286             goto L250;
00287         }
00288 
00289         if (w <= 0.) {
00290             dltlb = max(dltlb,tau);
00291         } else {
00292             dltub = min(dltub,tau);
00293         }
00294 
00295 /*        Calculate the new step */
00296 
00297         ++niter;
00298         c__ = w - delta[*n - 1] * dpsi - delta[*n] * dphi;
00299         a = (delta[*n - 1] + delta[*n]) * w - delta[*n - 1] * delta[*n] * (
00300                 dpsi + dphi);
00301         b = delta[*n - 1] * delta[*n] * w;
00302         if (c__ < 0.) {
00303             c__ = abs(c__);
00304         }
00305         if (c__ == 0.) {
00306 /*          ETA = B/A */
00307 /*           ETA = RHO - TAU */
00308             eta = dltub - tau;
00309         } else if (a >= 0.) {
00310             eta = (a + sqrt((d__1 = a * a - b * 4. * c__, abs(d__1)))) / (c__ 
00311                     * 2.);
00312         } else {
00313             eta = b * 2. / (a - sqrt((d__1 = a * a - b * 4. * c__, abs(d__1)))
00314                     );
00315         }
00316 
00317 /*        Note, eta should be positive if w is negative, and */
00318 /*        eta should be negative otherwise. However, */
00319 /*        if for some reason caused by roundoff, eta*w > 0, */
00320 /*        we simply use one Newton step instead. This way */
00321 /*        will guarantee eta*w < 0. */
00322 
00323         if (w * eta > 0.) {
00324             eta = -w / (dpsi + dphi);
00325         }
00326         temp = tau + eta;
00327         if (temp > dltub || temp < dltlb) {
00328             if (w < 0.) {
00329                 eta = (dltub - tau) / 2.;
00330             } else {
00331                 eta = (dltlb - tau) / 2.;
00332             }
00333         }
00334         i__1 = *n;
00335         for (j = 1; j <= i__1; ++j) {
00336             delta[j] -= eta;
00337 /* L50: */
00338         }
00339 
00340         tau += eta;
00341 
00342 /*        Evaluate PSI and the derivative DPSI */
00343 
00344         dpsi = 0.;
00345         psi = 0.;
00346         erretm = 0.;
00347         i__1 = ii;
00348         for (j = 1; j <= i__1; ++j) {
00349             temp = z__[j] / delta[j];
00350             psi += z__[j] * temp;
00351             dpsi += temp * temp;
00352             erretm += psi;
00353 /* L60: */
00354         }
00355         erretm = abs(erretm);
00356 
00357 /*        Evaluate PHI and the derivative DPHI */
00358 
00359         temp = z__[*n] / delta[*n];
00360         phi = z__[*n] * temp;
00361         dphi = temp * temp;
00362         erretm = (-phi - psi) * 8. + erretm - phi + rhoinv + abs(tau) * (dpsi 
00363                 + dphi);
00364 
00365         w = rhoinv + phi + psi;
00366 
00367 /*        Main loop to update the values of the array   DELTA */
00368 
00369         iter = niter + 1;
00370 
00371         for (niter = iter; niter <= 30; ++niter) {
00372 
00373 /*           Test for convergence */
00374 
00375             if (abs(w) <= eps * erretm) {
00376                 *dlam = d__[*i__] + tau;
00377                 goto L250;
00378             }
00379 
00380             if (w <= 0.) {
00381                 dltlb = max(dltlb,tau);
00382             } else {
00383                 dltub = min(dltub,tau);
00384             }
00385 
00386 /*           Calculate the new step */
00387 
00388             c__ = w - delta[*n - 1] * dpsi - delta[*n] * dphi;
00389             a = (delta[*n - 1] + delta[*n]) * w - delta[*n - 1] * delta[*n] * 
00390                     (dpsi + dphi);
00391             b = delta[*n - 1] * delta[*n] * w;
00392             if (a >= 0.) {
00393                 eta = (a + sqrt((d__1 = a * a - b * 4. * c__, abs(d__1)))) / (
00394                         c__ * 2.);
00395             } else {
00396                 eta = b * 2. / (a - sqrt((d__1 = a * a - b * 4. * c__, abs(
00397                         d__1))));
00398             }
00399 
00400 /*           Note, eta should be positive if w is negative, and */
00401 /*           eta should be negative otherwise. However, */
00402 /*           if for some reason caused by roundoff, eta*w > 0, */
00403 /*           we simply use one Newton step instead. This way */
00404 /*           will guarantee eta*w < 0. */
00405 
00406             if (w * eta > 0.) {
00407                 eta = -w / (dpsi + dphi);
00408             }
00409             temp = tau + eta;
00410             if (temp > dltub || temp < dltlb) {
00411                 if (w < 0.) {
00412                     eta = (dltub - tau) / 2.;
00413                 } else {
00414                     eta = (dltlb - tau) / 2.;
00415                 }
00416             }
00417             i__1 = *n;
00418             for (j = 1; j <= i__1; ++j) {
00419                 delta[j] -= eta;
00420 /* L70: */
00421             }
00422 
00423             tau += eta;
00424 
00425 /*           Evaluate PSI and the derivative DPSI */
00426 
00427             dpsi = 0.;
00428             psi = 0.;
00429             erretm = 0.;
00430             i__1 = ii;
00431             for (j = 1; j <= i__1; ++j) {
00432                 temp = z__[j] / delta[j];
00433                 psi += z__[j] * temp;
00434                 dpsi += temp * temp;
00435                 erretm += psi;
00436 /* L80: */
00437             }
00438             erretm = abs(erretm);
00439 
00440 /*           Evaluate PHI and the derivative DPHI */
00441 
00442             temp = z__[*n] / delta[*n];
00443             phi = z__[*n] * temp;
00444             dphi = temp * temp;
00445             erretm = (-phi - psi) * 8. + erretm - phi + rhoinv + abs(tau) * (
00446                     dpsi + dphi);
00447 
00448             w = rhoinv + phi + psi;
00449 /* L90: */
00450         }
00451 
00452 /*        Return with INFO = 1, NITER = MAXIT and not converged */
00453 
00454         *info = 1;
00455         *dlam = d__[*i__] + tau;
00456         goto L250;
00457 
00458 /*        End for the case I = N */
00459 
00460     } else {
00461 
00462 /*        The case for I < N */
00463 
00464         niter = 1;
00465         ip1 = *i__ + 1;
00466 
00467 /*        Calculate initial guess */
00468 
00469         del = d__[ip1] - d__[*i__];
00470         midpt = del / 2.;
00471         i__1 = *n;
00472         for (j = 1; j <= i__1; ++j) {
00473             delta[j] = d__[j] - d__[*i__] - midpt;
00474 /* L100: */
00475         }
00476 
00477         psi = 0.;
00478         i__1 = *i__ - 1;
00479         for (j = 1; j <= i__1; ++j) {
00480             psi += z__[j] * z__[j] / delta[j];
00481 /* L110: */
00482         }
00483 
00484         phi = 0.;
00485         i__1 = *i__ + 2;
00486         for (j = *n; j >= i__1; --j) {
00487             phi += z__[j] * z__[j] / delta[j];
00488 /* L120: */
00489         }
00490         c__ = rhoinv + psi + phi;
00491         w = c__ + z__[*i__] * z__[*i__] / delta[*i__] + z__[ip1] * z__[ip1] / 
00492                 delta[ip1];
00493 
00494         if (w > 0.) {
00495 
00496 /*           d(i)< the ith eigenvalue < (d(i)+d(i+1))/2 */
00497 
00498 /*           We choose d(i) as origin. */
00499 
00500             orgati = TRUE_;
00501             a = c__ * del + z__[*i__] * z__[*i__] + z__[ip1] * z__[ip1];
00502             b = z__[*i__] * z__[*i__] * del;
00503             if (a > 0.) {
00504                 tau = b * 2. / (a + sqrt((d__1 = a * a - b * 4. * c__, abs(
00505                         d__1))));
00506             } else {
00507                 tau = (a - sqrt((d__1 = a * a - b * 4. * c__, abs(d__1)))) / (
00508                         c__ * 2.);
00509             }
00510             dltlb = 0.;
00511             dltub = midpt;
00512         } else {
00513 
00514 /*           (d(i)+d(i+1))/2 <= the ith eigenvalue < d(i+1) */
00515 
00516 /*           We choose d(i+1) as origin. */
00517 
00518             orgati = FALSE_;
00519             a = c__ * del - z__[*i__] * z__[*i__] - z__[ip1] * z__[ip1];
00520             b = z__[ip1] * z__[ip1] * del;
00521             if (a < 0.) {
00522                 tau = b * 2. / (a - sqrt((d__1 = a * a + b * 4. * c__, abs(
00523                         d__1))));
00524             } else {
00525                 tau = -(a + sqrt((d__1 = a * a + b * 4. * c__, abs(d__1)))) / 
00526                         (c__ * 2.);
00527             }
00528             dltlb = -midpt;
00529             dltub = 0.;
00530         }
00531 
00532         if (orgati) {
00533             i__1 = *n;
00534             for (j = 1; j <= i__1; ++j) {
00535                 delta[j] = d__[j] - d__[*i__] - tau;
00536 /* L130: */
00537             }
00538         } else {
00539             i__1 = *n;
00540             for (j = 1; j <= i__1; ++j) {
00541                 delta[j] = d__[j] - d__[ip1] - tau;
00542 /* L140: */
00543             }
00544         }
00545         if (orgati) {
00546             ii = *i__;
00547         } else {
00548             ii = *i__ + 1;
00549         }
00550         iim1 = ii - 1;
00551         iip1 = ii + 1;
00552 
00553 /*        Evaluate PSI and the derivative DPSI */
00554 
00555         dpsi = 0.;
00556         psi = 0.;
00557         erretm = 0.;
00558         i__1 = iim1;
00559         for (j = 1; j <= i__1; ++j) {
00560             temp = z__[j] / delta[j];
00561             psi += z__[j] * temp;
00562             dpsi += temp * temp;
00563             erretm += psi;
00564 /* L150: */
00565         }
00566         erretm = abs(erretm);
00567 
00568 /*        Evaluate PHI and the derivative DPHI */
00569 
00570         dphi = 0.;
00571         phi = 0.;
00572         i__1 = iip1;
00573         for (j = *n; j >= i__1; --j) {
00574             temp = z__[j] / delta[j];
00575             phi += z__[j] * temp;
00576             dphi += temp * temp;
00577             erretm += phi;
00578 /* L160: */
00579         }
00580 
00581         w = rhoinv + phi + psi;
00582 
00583 /*        W is the value of the secular function with */
00584 /*        its ii-th element removed. */
00585 
00586         swtch3 = FALSE_;
00587         if (orgati) {
00588             if (w < 0.) {
00589                 swtch3 = TRUE_;
00590             }
00591         } else {
00592             if (w > 0.) {
00593                 swtch3 = TRUE_;
00594             }
00595         }
00596         if (ii == 1 || ii == *n) {
00597             swtch3 = FALSE_;
00598         }
00599 
00600         temp = z__[ii] / delta[ii];
00601         dw = dpsi + dphi + temp * temp;
00602         temp = z__[ii] * temp;
00603         w += temp;
00604         erretm = (phi - psi) * 8. + erretm + rhoinv * 2. + abs(temp) * 3. + 
00605                 abs(tau) * dw;
00606 
00607 /*        Test for convergence */
00608 
00609         if (abs(w) <= eps * erretm) {
00610             if (orgati) {
00611                 *dlam = d__[*i__] + tau;
00612             } else {
00613                 *dlam = d__[ip1] + tau;
00614             }
00615             goto L250;
00616         }
00617 
00618         if (w <= 0.) {
00619             dltlb = max(dltlb,tau);
00620         } else {
00621             dltub = min(dltub,tau);
00622         }
00623 
00624 /*        Calculate the new step */
00625 
00626         ++niter;
00627         if (! swtch3) {
00628             if (orgati) {
00629 /* Computing 2nd power */
00630                 d__1 = z__[*i__] / delta[*i__];
00631                 c__ = w - delta[ip1] * dw - (d__[*i__] - d__[ip1]) * (d__1 * 
00632                         d__1);
00633             } else {
00634 /* Computing 2nd power */
00635                 d__1 = z__[ip1] / delta[ip1];
00636                 c__ = w - delta[*i__] * dw - (d__[ip1] - d__[*i__]) * (d__1 * 
00637                         d__1);
00638             }
00639             a = (delta[*i__] + delta[ip1]) * w - delta[*i__] * delta[ip1] * 
00640                     dw;
00641             b = delta[*i__] * delta[ip1] * w;
00642             if (c__ == 0.) {
00643                 if (a == 0.) {
00644                     if (orgati) {
00645                         a = z__[*i__] * z__[*i__] + delta[ip1] * delta[ip1] * 
00646                                 (dpsi + dphi);
00647                     } else {
00648                         a = z__[ip1] * z__[ip1] + delta[*i__] * delta[*i__] * 
00649                                 (dpsi + dphi);
00650                     }
00651                 }
00652                 eta = b / a;
00653             } else if (a <= 0.) {
00654                 eta = (a - sqrt((d__1 = a * a - b * 4. * c__, abs(d__1)))) / (
00655                         c__ * 2.);
00656             } else {
00657                 eta = b * 2. / (a + sqrt((d__1 = a * a - b * 4. * c__, abs(
00658                         d__1))));
00659             }
00660         } else {
00661 
00662 /*           Interpolation using THREE most relevant poles */
00663 
00664             temp = rhoinv + psi + phi;
00665             if (orgati) {
00666                 temp1 = z__[iim1] / delta[iim1];
00667                 temp1 *= temp1;
00668                 c__ = temp - delta[iip1] * (dpsi + dphi) - (d__[iim1] - d__[
00669                         iip1]) * temp1;
00670                 zz[0] = z__[iim1] * z__[iim1];
00671                 zz[2] = delta[iip1] * delta[iip1] * (dpsi - temp1 + dphi);
00672             } else {
00673                 temp1 = z__[iip1] / delta[iip1];
00674                 temp1 *= temp1;
00675                 c__ = temp - delta[iim1] * (dpsi + dphi) - (d__[iip1] - d__[
00676                         iim1]) * temp1;
00677                 zz[0] = delta[iim1] * delta[iim1] * (dpsi + (dphi - temp1));
00678                 zz[2] = z__[iip1] * z__[iip1];
00679             }
00680             zz[1] = z__[ii] * z__[ii];
00681             dlaed6_(&niter, &orgati, &c__, &delta[iim1], zz, &w, &eta, info);
00682             if (*info != 0) {
00683                 goto L250;
00684             }
00685         }
00686 
00687 /*        Note, eta should be positive if w is negative, and */
00688 /*        eta should be negative otherwise. However, */
00689 /*        if for some reason caused by roundoff, eta*w > 0, */
00690 /*        we simply use one Newton step instead. This way */
00691 /*        will guarantee eta*w < 0. */
00692 
00693         if (w * eta >= 0.) {
00694             eta = -w / dw;
00695         }
00696         temp = tau + eta;
00697         if (temp > dltub || temp < dltlb) {
00698             if (w < 0.) {
00699                 eta = (dltub - tau) / 2.;
00700             } else {
00701                 eta = (dltlb - tau) / 2.;
00702             }
00703         }
00704 
00705         prew = w;
00706 
00707         i__1 = *n;
00708         for (j = 1; j <= i__1; ++j) {
00709             delta[j] -= eta;
00710 /* L180: */
00711         }
00712 
00713 /*        Evaluate PSI and the derivative DPSI */
00714 
00715         dpsi = 0.;
00716         psi = 0.;
00717         erretm = 0.;
00718         i__1 = iim1;
00719         for (j = 1; j <= i__1; ++j) {
00720             temp = z__[j] / delta[j];
00721             psi += z__[j] * temp;
00722             dpsi += temp * temp;
00723             erretm += psi;
00724 /* L190: */
00725         }
00726         erretm = abs(erretm);
00727 
00728 /*        Evaluate PHI and the derivative DPHI */
00729 
00730         dphi = 0.;
00731         phi = 0.;
00732         i__1 = iip1;
00733         for (j = *n; j >= i__1; --j) {
00734             temp = z__[j] / delta[j];
00735             phi += z__[j] * temp;
00736             dphi += temp * temp;
00737             erretm += phi;
00738 /* L200: */
00739         }
00740 
00741         temp = z__[ii] / delta[ii];
00742         dw = dpsi + dphi + temp * temp;
00743         temp = z__[ii] * temp;
00744         w = rhoinv + phi + psi + temp;
00745         erretm = (phi - psi) * 8. + erretm + rhoinv * 2. + abs(temp) * 3. + (
00746                 d__1 = tau + eta, abs(d__1)) * dw;
00747 
00748         swtch = FALSE_;
00749         if (orgati) {
00750             if (-w > abs(prew) / 10.) {
00751                 swtch = TRUE_;
00752             }
00753         } else {
00754             if (w > abs(prew) / 10.) {
00755                 swtch = TRUE_;
00756             }
00757         }
00758 
00759         tau += eta;
00760 
00761 /*        Main loop to update the values of the array   DELTA */
00762 
00763         iter = niter + 1;
00764 
00765         for (niter = iter; niter <= 30; ++niter) {
00766 
00767 /*           Test for convergence */
00768 
00769             if (abs(w) <= eps * erretm) {
00770                 if (orgati) {
00771                     *dlam = d__[*i__] + tau;
00772                 } else {
00773                     *dlam = d__[ip1] + tau;
00774                 }
00775                 goto L250;
00776             }
00777 
00778             if (w <= 0.) {
00779                 dltlb = max(dltlb,tau);
00780             } else {
00781                 dltub = min(dltub,tau);
00782             }
00783 
00784 /*           Calculate the new step */
00785 
00786             if (! swtch3) {
00787                 if (! swtch) {
00788                     if (orgati) {
00789 /* Computing 2nd power */
00790                         d__1 = z__[*i__] / delta[*i__];
00791                         c__ = w - delta[ip1] * dw - (d__[*i__] - d__[ip1]) * (
00792                                 d__1 * d__1);
00793                     } else {
00794 /* Computing 2nd power */
00795                         d__1 = z__[ip1] / delta[ip1];
00796                         c__ = w - delta[*i__] * dw - (d__[ip1] - d__[*i__]) * 
00797                                 (d__1 * d__1);
00798                     }
00799                 } else {
00800                     temp = z__[ii] / delta[ii];
00801                     if (orgati) {
00802                         dpsi += temp * temp;
00803                     } else {
00804                         dphi += temp * temp;
00805                     }
00806                     c__ = w - delta[*i__] * dpsi - delta[ip1] * dphi;
00807                 }
00808                 a = (delta[*i__] + delta[ip1]) * w - delta[*i__] * delta[ip1] 
00809                         * dw;
00810                 b = delta[*i__] * delta[ip1] * w;
00811                 if (c__ == 0.) {
00812                     if (a == 0.) {
00813                         if (! swtch) {
00814                             if (orgati) {
00815                                 a = z__[*i__] * z__[*i__] + delta[ip1] * 
00816                                         delta[ip1] * (dpsi + dphi);
00817                             } else {
00818                                 a = z__[ip1] * z__[ip1] + delta[*i__] * delta[
00819                                         *i__] * (dpsi + dphi);
00820                             }
00821                         } else {
00822                             a = delta[*i__] * delta[*i__] * dpsi + delta[ip1] 
00823                                     * delta[ip1] * dphi;
00824                         }
00825                     }
00826                     eta = b / a;
00827                 } else if (a <= 0.) {
00828                     eta = (a - sqrt((d__1 = a * a - b * 4. * c__, abs(d__1))))
00829                              / (c__ * 2.);
00830                 } else {
00831                     eta = b * 2. / (a + sqrt((d__1 = a * a - b * 4. * c__, 
00832                             abs(d__1))));
00833                 }
00834             } else {
00835 
00836 /*              Interpolation using THREE most relevant poles */
00837 
00838                 temp = rhoinv + psi + phi;
00839                 if (swtch) {
00840                     c__ = temp - delta[iim1] * dpsi - delta[iip1] * dphi;
00841                     zz[0] = delta[iim1] * delta[iim1] * dpsi;
00842                     zz[2] = delta[iip1] * delta[iip1] * dphi;
00843                 } else {
00844                     if (orgati) {
00845                         temp1 = z__[iim1] / delta[iim1];
00846                         temp1 *= temp1;
00847                         c__ = temp - delta[iip1] * (dpsi + dphi) - (d__[iim1] 
00848                                 - d__[iip1]) * temp1;
00849                         zz[0] = z__[iim1] * z__[iim1];
00850                         zz[2] = delta[iip1] * delta[iip1] * (dpsi - temp1 + 
00851                                 dphi);
00852                     } else {
00853                         temp1 = z__[iip1] / delta[iip1];
00854                         temp1 *= temp1;
00855                         c__ = temp - delta[iim1] * (dpsi + dphi) - (d__[iip1] 
00856                                 - d__[iim1]) * temp1;
00857                         zz[0] = delta[iim1] * delta[iim1] * (dpsi + (dphi - 
00858                                 temp1));
00859                         zz[2] = z__[iip1] * z__[iip1];
00860                     }
00861                 }
00862                 dlaed6_(&niter, &orgati, &c__, &delta[iim1], zz, &w, &eta, 
00863                         info);
00864                 if (*info != 0) {
00865                     goto L250;
00866                 }
00867             }
00868 
00869 /*           Note, eta should be positive if w is negative, and */
00870 /*           eta should be negative otherwise. However, */
00871 /*           if for some reason caused by roundoff, eta*w > 0, */
00872 /*           we simply use one Newton step instead. This way */
00873 /*           will guarantee eta*w < 0. */
00874 
00875             if (w * eta >= 0.) {
00876                 eta = -w / dw;
00877             }
00878             temp = tau + eta;
00879             if (temp > dltub || temp < dltlb) {
00880                 if (w < 0.) {
00881                     eta = (dltub - tau) / 2.;
00882                 } else {
00883                     eta = (dltlb - tau) / 2.;
00884                 }
00885             }
00886 
00887             i__1 = *n;
00888             for (j = 1; j <= i__1; ++j) {
00889                 delta[j] -= eta;
00890 /* L210: */
00891             }
00892 
00893             tau += eta;
00894             prew = w;
00895 
00896 /*           Evaluate PSI and the derivative DPSI */
00897 
00898             dpsi = 0.;
00899             psi = 0.;
00900             erretm = 0.;
00901             i__1 = iim1;
00902             for (j = 1; j <= i__1; ++j) {
00903                 temp = z__[j] / delta[j];
00904                 psi += z__[j] * temp;
00905                 dpsi += temp * temp;
00906                 erretm += psi;
00907 /* L220: */
00908             }
00909             erretm = abs(erretm);
00910 
00911 /*           Evaluate PHI and the derivative DPHI */
00912 
00913             dphi = 0.;
00914             phi = 0.;
00915             i__1 = iip1;
00916             for (j = *n; j >= i__1; --j) {
00917                 temp = z__[j] / delta[j];
00918                 phi += z__[j] * temp;
00919                 dphi += temp * temp;
00920                 erretm += phi;
00921 /* L230: */
00922             }
00923 
00924             temp = z__[ii] / delta[ii];
00925             dw = dpsi + dphi + temp * temp;
00926             temp = z__[ii] * temp;
00927             w = rhoinv + phi + psi + temp;
00928             erretm = (phi - psi) * 8. + erretm + rhoinv * 2. + abs(temp) * 3. 
00929                     + abs(tau) * dw;
00930             if (w * prew > 0. && abs(w) > abs(prew) / 10.) {
00931                 swtch = ! swtch;
00932             }
00933 
00934 /* L240: */
00935         }
00936 
00937 /*        Return with INFO = 1, NITER = MAXIT and not converged */
00938 
00939         *info = 1;
00940         if (orgati) {
00941             *dlam = d__[*i__] + tau;
00942         } else {
00943             *dlam = d__[ip1] + tau;
00944         }
00945 
00946     }
00947 
00948 L250:
00949 
00950     return 0;
00951 
00952 /*     End of DLAED4 */
00953 
00954 } /* dlaed4_ */


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:55:46