dlasq3.c
Go to the documentation of this file.
00001 /* dlasq3.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 dlasq3_(integer *i0, integer *n0, doublereal *z__, 
00017         integer *pp, doublereal *dmin__, doublereal *sigma, doublereal *desig, 
00018          doublereal *qmax, integer *nfail, integer *iter, integer *ndiv, 
00019         logical *ieee, integer *ttype, doublereal *dmin1, doublereal *dmin2, 
00020         doublereal *dn, doublereal *dn1, doublereal *dn2, doublereal *g, 
00021         doublereal *tau)
00022 {
00023     /* System generated locals */
00024     integer i__1;
00025     doublereal d__1, d__2;
00026 
00027     /* Builtin functions */
00028     double sqrt(doublereal);
00029 
00030     /* Local variables */
00031     doublereal s, t;
00032     integer j4, nn;
00033     doublereal eps, tol;
00034     integer n0in, ipn4;
00035     doublereal tol2, temp;
00036     extern /* Subroutine */ int dlasq4_(integer *, integer *, doublereal *, 
00037             integer *, integer *, doublereal *, doublereal *, doublereal *, 
00038             doublereal *, doublereal *, doublereal *, doublereal *, integer *, 
00039              doublereal *), dlasq5_(integer *, integer *, doublereal *, 
00040             integer *, doublereal *, doublereal *, doublereal *, doublereal *, 
00041              doublereal *, doublereal *, doublereal *, logical *), dlasq6_(
00042             integer *, integer *, doublereal *, integer *, doublereal *, 
00043             doublereal *, doublereal *, doublereal *, doublereal *, 
00044             doublereal *);
00045     extern doublereal dlamch_(char *);
00046     extern logical disnan_(doublereal *);
00047 
00048 
00049 /*  -- LAPACK routine (version 3.2)                                    -- */
00050 
00051 /*  -- Contributed by Osni Marques of the Lawrence Berkeley National   -- */
00052 /*  -- Laboratory and Beresford Parlett of the Univ. of California at  -- */
00053 /*  -- Berkeley                                                        -- */
00054 /*  -- November 2008                                                   -- */
00055 
00056 /*  -- LAPACK is a software package provided by Univ. of Tennessee,    -- */
00057 /*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */
00058 
00059 /*     .. Scalar Arguments .. */
00060 /*     .. */
00061 /*     .. Array Arguments .. */
00062 /*     .. */
00063 
00064 /*  Purpose */
00065 /*  ======= */
00066 
00067 /*  DLASQ3 checks for deflation, computes a shift (TAU) and calls dqds. */
00068 /*  In case of failure it changes shifts, and tries again until output */
00069 /*  is positive. */
00070 
00071 /*  Arguments */
00072 /*  ========= */
00073 
00074 /*  I0     (input) INTEGER */
00075 /*         First index. */
00076 
00077 /*  N0     (input) INTEGER */
00078 /*         Last index. */
00079 
00080 /*  Z      (input) DOUBLE PRECISION array, dimension ( 4*N ) */
00081 /*         Z holds the qd array. */
00082 
00083 /*  PP     (input/output) INTEGER */
00084 /*         PP=0 for ping, PP=1 for pong. */
00085 /*         PP=2 indicates that flipping was applied to the Z array */
00086 /*         and that the initial tests for deflation should not be */
00087 /*         performed. */
00088 
00089 /*  DMIN   (output) DOUBLE PRECISION */
00090 /*         Minimum value of d. */
00091 
00092 /*  SIGMA  (output) DOUBLE PRECISION */
00093 /*         Sum of shifts used in current segment. */
00094 
00095 /*  DESIG  (input/output) DOUBLE PRECISION */
00096 /*         Lower order part of SIGMA */
00097 
00098 /*  QMAX   (input) DOUBLE PRECISION */
00099 /*         Maximum value of q. */
00100 
00101 /*  NFAIL  (output) INTEGER */
00102 /*         Number of times shift was too big. */
00103 
00104 /*  ITER   (output) INTEGER */
00105 /*         Number of iterations. */
00106 
00107 /*  NDIV   (output) INTEGER */
00108 /*         Number of divisions. */
00109 
00110 /*  IEEE   (input) LOGICAL */
00111 /*         Flag for IEEE or non IEEE arithmetic (passed to DLASQ5). */
00112 
00113 /*  TTYPE  (input/output) INTEGER */
00114 /*         Shift type. */
00115 
00116 /*  DMIN1, DMIN2, DN, DN1, DN2, G, TAU (input/output) DOUBLE PRECISION */
00117 /*         These are passed as arguments in order to save their values */
00118 /*         between calls to DLASQ3. */
00119 
00120 /*  ===================================================================== */
00121 
00122 /*     .. Parameters .. */
00123 /*     .. */
00124 /*     .. Local Scalars .. */
00125 /*     .. */
00126 /*     .. External Subroutines .. */
00127 /*     .. */
00128 /*     .. External Function .. */
00129 /*     .. */
00130 /*     .. Intrinsic Functions .. */
00131 /*     .. */
00132 /*     .. Executable Statements .. */
00133 
00134     /* Parameter adjustments */
00135     --z__;
00136 
00137     /* Function Body */
00138     n0in = *n0;
00139     eps = dlamch_("Precision");
00140     tol = eps * 100.;
00141 /* Computing 2nd power */
00142     d__1 = tol;
00143     tol2 = d__1 * d__1;
00144 
00145 /*     Check for deflation. */
00146 
00147 L10:
00148 
00149     if (*n0 < *i0) {
00150         return 0;
00151     }
00152     if (*n0 == *i0) {
00153         goto L20;
00154     }
00155     nn = (*n0 << 2) + *pp;
00156     if (*n0 == *i0 + 1) {
00157         goto L40;
00158     }
00159 
00160 /*     Check whether E(N0-1) is negligible, 1 eigenvalue. */
00161 
00162     if (z__[nn - 5] > tol2 * (*sigma + z__[nn - 3]) && z__[nn - (*pp << 1) - 
00163             4] > tol2 * z__[nn - 7]) {
00164         goto L30;
00165     }
00166 
00167 L20:
00168 
00169     z__[(*n0 << 2) - 3] = z__[(*n0 << 2) + *pp - 3] + *sigma;
00170     --(*n0);
00171     goto L10;
00172 
00173 /*     Check  whether E(N0-2) is negligible, 2 eigenvalues. */
00174 
00175 L30:
00176 
00177     if (z__[nn - 9] > tol2 * *sigma && z__[nn - (*pp << 1) - 8] > tol2 * z__[
00178             nn - 11]) {
00179         goto L50;
00180     }
00181 
00182 L40:
00183 
00184     if (z__[nn - 3] > z__[nn - 7]) {
00185         s = z__[nn - 3];
00186         z__[nn - 3] = z__[nn - 7];
00187         z__[nn - 7] = s;
00188     }
00189     if (z__[nn - 5] > z__[nn - 3] * tol2) {
00190         t = (z__[nn - 7] - z__[nn - 3] + z__[nn - 5]) * .5;
00191         s = z__[nn - 3] * (z__[nn - 5] / t);
00192         if (s <= t) {
00193             s = z__[nn - 3] * (z__[nn - 5] / (t * (sqrt(s / t + 1.) + 1.)));
00194         } else {
00195             s = z__[nn - 3] * (z__[nn - 5] / (t + sqrt(t) * sqrt(t + s)));
00196         }
00197         t = z__[nn - 7] + (s + z__[nn - 5]);
00198         z__[nn - 3] *= z__[nn - 7] / t;
00199         z__[nn - 7] = t;
00200     }
00201     z__[(*n0 << 2) - 7] = z__[nn - 7] + *sigma;
00202     z__[(*n0 << 2) - 3] = z__[nn - 3] + *sigma;
00203     *n0 += -2;
00204     goto L10;
00205 
00206 L50:
00207     if (*pp == 2) {
00208         *pp = 0;
00209     }
00210 
00211 /*     Reverse the qd-array, if warranted. */
00212 
00213     if (*dmin__ <= 0. || *n0 < n0in) {
00214         if (z__[(*i0 << 2) + *pp - 3] * 1.5 < z__[(*n0 << 2) + *pp - 3]) {
00215             ipn4 = *i0 + *n0 << 2;
00216             i__1 = *i0 + *n0 - 1 << 1;
00217             for (j4 = *i0 << 2; j4 <= i__1; j4 += 4) {
00218                 temp = z__[j4 - 3];
00219                 z__[j4 - 3] = z__[ipn4 - j4 - 3];
00220                 z__[ipn4 - j4 - 3] = temp;
00221                 temp = z__[j4 - 2];
00222                 z__[j4 - 2] = z__[ipn4 - j4 - 2];
00223                 z__[ipn4 - j4 - 2] = temp;
00224                 temp = z__[j4 - 1];
00225                 z__[j4 - 1] = z__[ipn4 - j4 - 5];
00226                 z__[ipn4 - j4 - 5] = temp;
00227                 temp = z__[j4];
00228                 z__[j4] = z__[ipn4 - j4 - 4];
00229                 z__[ipn4 - j4 - 4] = temp;
00230 /* L60: */
00231             }
00232             if (*n0 - *i0 <= 4) {
00233                 z__[(*n0 << 2) + *pp - 1] = z__[(*i0 << 2) + *pp - 1];
00234                 z__[(*n0 << 2) - *pp] = z__[(*i0 << 2) - *pp];
00235             }
00236 /* Computing MIN */
00237             d__1 = *dmin2, d__2 = z__[(*n0 << 2) + *pp - 1];
00238             *dmin2 = min(d__1,d__2);
00239 /* Computing MIN */
00240             d__1 = z__[(*n0 << 2) + *pp - 1], d__2 = z__[(*i0 << 2) + *pp - 1]
00241                     , d__1 = min(d__1,d__2), d__2 = z__[(*i0 << 2) + *pp + 3];
00242             z__[(*n0 << 2) + *pp - 1] = min(d__1,d__2);
00243 /* Computing MIN */
00244             d__1 = z__[(*n0 << 2) - *pp], d__2 = z__[(*i0 << 2) - *pp], d__1 =
00245                      min(d__1,d__2), d__2 = z__[(*i0 << 2) - *pp + 4];
00246             z__[(*n0 << 2) - *pp] = min(d__1,d__2);
00247 /* Computing MAX */
00248             d__1 = *qmax, d__2 = z__[(*i0 << 2) + *pp - 3], d__1 = max(d__1,
00249                     d__2), d__2 = z__[(*i0 << 2) + *pp + 1];
00250             *qmax = max(d__1,d__2);
00251             *dmin__ = -0.;
00252         }
00253     }
00254 
00255 /*     Choose a shift. */
00256 
00257     dlasq4_(i0, n0, &z__[1], pp, &n0in, dmin__, dmin1, dmin2, dn, dn1, dn2, 
00258             tau, ttype, g);
00259 
00260 /*     Call dqds until DMIN > 0. */
00261 
00262 L70:
00263 
00264     dlasq5_(i0, n0, &z__[1], pp, tau, dmin__, dmin1, dmin2, dn, dn1, dn2, 
00265             ieee);
00266 
00267     *ndiv += *n0 - *i0 + 2;
00268     ++(*iter);
00269 
00270 /*     Check status. */
00271 
00272     if (*dmin__ >= 0. && *dmin1 > 0.) {
00273 
00274 /*        Success. */
00275 
00276         goto L90;
00277 
00278     } else if (*dmin__ < 0. && *dmin1 > 0. && z__[(*n0 - 1 << 2) - *pp] < tol 
00279             * (*sigma + *dn1) && abs(*dn) < tol * *sigma) {
00280 
00281 /*        Convergence hidden by negative DN. */
00282 
00283         z__[(*n0 - 1 << 2) - *pp + 2] = 0.;
00284         *dmin__ = 0.;
00285         goto L90;
00286     } else if (*dmin__ < 0.) {
00287 
00288 /*        TAU too big. Select new TAU and try again. */
00289 
00290         ++(*nfail);
00291         if (*ttype < -22) {
00292 
00293 /*           Failed twice. Play it safe. */
00294 
00295             *tau = 0.;
00296         } else if (*dmin1 > 0.) {
00297 
00298 /*           Late failure. Gives excellent shift. */
00299 
00300             *tau = (*tau + *dmin__) * (1. - eps * 2.);
00301             *ttype += -11;
00302         } else {
00303 
00304 /*           Early failure. Divide by 4. */
00305 
00306             *tau *= .25;
00307             *ttype += -12;
00308         }
00309         goto L70;
00310     } else if (disnan_(dmin__)) {
00311 
00312 /*        NaN. */
00313 
00314         if (*tau == 0.) {
00315             goto L80;
00316         } else {
00317             *tau = 0.;
00318             goto L70;
00319         }
00320     } else {
00321 
00322 /*        Possible underflow. Play it safe. */
00323 
00324         goto L80;
00325     }
00326 
00327 /*     Risk of underflow. */
00328 
00329 L80:
00330     dlasq6_(i0, n0, &z__[1], pp, dmin__, dmin1, dmin2, dn, dn1, dn2);
00331     *ndiv += *n0 - *i0 + 2;
00332     ++(*iter);
00333     *tau = 0.;
00334 
00335 L90:
00336     if (*tau < *sigma) {
00337         *desig += *tau;
00338         t = *sigma + *desig;
00339         *desig -= t - *sigma;
00340     } else {
00341         t = *sigma + *tau;
00342         *desig = *sigma - (t - *tau) + *desig;
00343     }
00344     *sigma = t;
00345 
00346     return 0;
00347 
00348 /*     End of DLASQ3 */
00349 
00350 } /* dlasq3_ */


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