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


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:56:09