dlasq2.c
Go to the documentation of this file.
00001 /* dlasq2.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 /* Table of constant values */
00017 
00018 static integer c__1 = 1;
00019 static integer c__2 = 2;
00020 static integer c__10 = 10;
00021 static integer c__3 = 3;
00022 static integer c__4 = 4;
00023 static integer c__11 = 11;
00024 
00025 /* Subroutine */ int dlasq2_(integer *n, doublereal *z__, integer *info)
00026 {
00027     /* System generated locals */
00028     integer i__1, i__2, i__3;
00029     doublereal d__1, d__2;
00030 
00031     /* Builtin functions */
00032     double sqrt(doublereal);
00033 
00034     /* Local variables */
00035     doublereal d__, e, g;
00036     integer k;
00037     doublereal s, t;
00038     integer i0, i4, n0;
00039     doublereal dn;
00040     integer pp;
00041     doublereal dn1, dn2, dee, eps, tau, tol;
00042     integer ipn4;
00043     doublereal tol2;
00044     logical ieee;
00045     integer nbig;
00046     doublereal dmin__, emin, emax;
00047     integer kmin, ndiv, iter;
00048     doublereal qmin, temp, qmax, zmax;
00049     integer splt;
00050     doublereal dmin1, dmin2;
00051     integer nfail;
00052     doublereal desig, trace, sigma;
00053     integer iinfo, ttype;
00054     extern /* Subroutine */ int dlasq3_(integer *, integer *, doublereal *, 
00055             integer *, doublereal *, doublereal *, doublereal *, doublereal *, 
00056              integer *, integer *, integer *, logical *, integer *, 
00057             doublereal *, doublereal *, doublereal *, doublereal *, 
00058             doublereal *, doublereal *, doublereal *);
00059     extern doublereal dlamch_(char *);
00060     doublereal deemin;
00061     integer iwhila, iwhilb;
00062     doublereal oldemn, safmin;
00063     extern /* Subroutine */ int xerbla_(char *, integer *);
00064     extern integer ilaenv_(integer *, char *, char *, integer *, integer *, 
00065             integer *, integer *);
00066     extern /* Subroutine */ int dlasrt_(char *, integer *, doublereal *, 
00067             integer *);
00068 
00069 
00070 /*  -- LAPACK routine (version 3.2)                                    -- */
00071 
00072 /*  -- Contributed by Osni Marques of the Lawrence Berkeley National   -- */
00073 /*  -- Laboratory and Beresford Parlett of the Univ. of California at  -- */
00074 /*  -- Berkeley                                                        -- */
00075 /*  -- November 2008                                                   -- */
00076 
00077 /*  -- LAPACK is a software package provided by Univ. of Tennessee,    -- */
00078 /*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */
00079 
00080 /*     .. Scalar Arguments .. */
00081 /*     .. */
00082 /*     .. Array Arguments .. */
00083 /*     .. */
00084 
00085 /*  Purpose */
00086 /*  ======= */
00087 
00088 /*  DLASQ2 computes all the eigenvalues of the symmetric positive */
00089 /*  definite tridiagonal matrix associated with the qd array Z to high */
00090 /*  relative accuracy are computed to high relative accuracy, in the */
00091 /*  absence of denormalization, underflow and overflow. */
00092 
00093 /*  To see the relation of Z to the tridiagonal matrix, let L be a */
00094 /*  unit lower bidiagonal matrix with subdiagonals Z(2,4,6,,..) and */
00095 /*  let U be an upper bidiagonal matrix with 1's above and diagonal */
00096 /*  Z(1,3,5,,..). The tridiagonal is L*U or, if you prefer, the */
00097 /*  symmetric tridiagonal to which it is similar. */
00098 
00099 /*  Note : DLASQ2 defines a logical variable, IEEE, which is true */
00100 /*  on machines which follow ieee-754 floating-point standard in their */
00101 /*  handling of infinities and NaNs, and false otherwise. This variable */
00102 /*  is passed to DLASQ3. */
00103 
00104 /*  Arguments */
00105 /*  ========= */
00106 
00107 /*  N     (input) INTEGER */
00108 /*        The number of rows and columns in the matrix. N >= 0. */
00109 
00110 /*  Z     (input/output) DOUBLE PRECISION array, dimension ( 4*N ) */
00111 /*        On entry Z holds the qd array. On exit, entries 1 to N hold */
00112 /*        the eigenvalues in decreasing order, Z( 2*N+1 ) holds the */
00113 /*        trace, and Z( 2*N+2 ) holds the sum of the eigenvalues. If */
00114 /*        N > 2, then Z( 2*N+3 ) holds the iteration count, Z( 2*N+4 ) */
00115 /*        holds NDIVS/NIN^2, and Z( 2*N+5 ) holds the percentage of */
00116 /*        shifts that failed. */
00117 
00118 /*  INFO  (output) INTEGER */
00119 /*        = 0: successful exit */
00120 /*        < 0: if the i-th argument is a scalar and had an illegal */
00121 /*             value, then INFO = -i, if the i-th argument is an */
00122 /*             array and the j-entry had an illegal value, then */
00123 /*             INFO = -(i*100+j) */
00124 /*        > 0: the algorithm failed */
00125 /*              = 1, a split was marked by a positive value in E */
00126 /*              = 2, current block of Z not diagonalized after 30*N */
00127 /*                   iterations (in inner while loop) */
00128 /*              = 3, termination criterion of outer while loop not met */
00129 /*                   (program created more than N unreduced blocks) */
00130 
00131 /*  Further Details */
00132 /*  =============== */
00133 /*  Local Variables: I0:N0 defines a current unreduced segment of Z. */
00134 /*  The shifts are accumulated in SIGMA. Iteration count is in ITER. */
00135 /*  Ping-pong is controlled by PP (alternates between 0 and 1). */
00136 
00137 /*  ===================================================================== */
00138 
00139 /*     .. Parameters .. */
00140 /*     .. */
00141 /*     .. Local Scalars .. */
00142 /*     .. */
00143 /*     .. External Subroutines .. */
00144 /*     .. */
00145 /*     .. External Functions .. */
00146 /*     .. */
00147 /*     .. Intrinsic Functions .. */
00148 /*     .. */
00149 /*     .. Executable Statements .. */
00150 
00151 /*     Test the input arguments. */
00152 /*     (in case DLASQ2 is not called by DLASQ1) */
00153 
00154     /* Parameter adjustments */
00155     --z__;
00156 
00157     /* Function Body */
00158     *info = 0;
00159     eps = dlamch_("Precision");
00160     safmin = dlamch_("Safe minimum");
00161     tol = eps * 100.;
00162 /* Computing 2nd power */
00163     d__1 = tol;
00164     tol2 = d__1 * d__1;
00165 
00166     if (*n < 0) {
00167         *info = -1;
00168         xerbla_("DLASQ2", &c__1);
00169         return 0;
00170     } else if (*n == 0) {
00171         return 0;
00172     } else if (*n == 1) {
00173 
00174 /*        1-by-1 case. */
00175 
00176         if (z__[1] < 0.) {
00177             *info = -201;
00178             xerbla_("DLASQ2", &c__2);
00179         }
00180         return 0;
00181     } else if (*n == 2) {
00182 
00183 /*        2-by-2 case. */
00184 
00185         if (z__[2] < 0. || z__[3] < 0.) {
00186             *info = -2;
00187             xerbla_("DLASQ2", &c__2);
00188             return 0;
00189         } else if (z__[3] > z__[1]) {
00190             d__ = z__[3];
00191             z__[3] = z__[1];
00192             z__[1] = d__;
00193         }
00194         z__[5] = z__[1] + z__[2] + z__[3];
00195         if (z__[2] > z__[3] * tol2) {
00196             t = (z__[1] - z__[3] + z__[2]) * .5;
00197             s = z__[3] * (z__[2] / t);
00198             if (s <= t) {
00199                 s = z__[3] * (z__[2] / (t * (sqrt(s / t + 1.) + 1.)));
00200             } else {
00201                 s = z__[3] * (z__[2] / (t + sqrt(t) * sqrt(t + s)));
00202             }
00203             t = z__[1] + (s + z__[2]);
00204             z__[3] *= z__[1] / t;
00205             z__[1] = t;
00206         }
00207         z__[2] = z__[3];
00208         z__[6] = z__[2] + z__[1];
00209         return 0;
00210     }
00211 
00212 /*     Check for negative data and compute sums of q's and e's. */
00213 
00214     z__[*n * 2] = 0.;
00215     emin = z__[2];
00216     qmax = 0.;
00217     zmax = 0.;
00218     d__ = 0.;
00219     e = 0.;
00220 
00221     i__1 = *n - 1 << 1;
00222     for (k = 1; k <= i__1; k += 2) {
00223         if (z__[k] < 0.) {
00224             *info = -(k + 200);
00225             xerbla_("DLASQ2", &c__2);
00226             return 0;
00227         } else if (z__[k + 1] < 0.) {
00228             *info = -(k + 201);
00229             xerbla_("DLASQ2", &c__2);
00230             return 0;
00231         }
00232         d__ += z__[k];
00233         e += z__[k + 1];
00234 /* Computing MAX */
00235         d__1 = qmax, d__2 = z__[k];
00236         qmax = max(d__1,d__2);
00237 /* Computing MIN */
00238         d__1 = emin, d__2 = z__[k + 1];
00239         emin = min(d__1,d__2);
00240 /* Computing MAX */
00241         d__1 = max(qmax,zmax), d__2 = z__[k + 1];
00242         zmax = max(d__1,d__2);
00243 /* L10: */
00244     }
00245     if (z__[(*n << 1) - 1] < 0.) {
00246         *info = -((*n << 1) + 199);
00247         xerbla_("DLASQ2", &c__2);
00248         return 0;
00249     }
00250     d__ += z__[(*n << 1) - 1];
00251 /* Computing MAX */
00252     d__1 = qmax, d__2 = z__[(*n << 1) - 1];
00253     qmax = max(d__1,d__2);
00254     zmax = max(qmax,zmax);
00255 
00256 /*     Check for diagonality. */
00257 
00258     if (e == 0.) {
00259         i__1 = *n;
00260         for (k = 2; k <= i__1; ++k) {
00261             z__[k] = z__[(k << 1) - 1];
00262 /* L20: */
00263         }
00264         dlasrt_("D", n, &z__[1], &iinfo);
00265         z__[(*n << 1) - 1] = d__;
00266         return 0;
00267     }
00268 
00269     trace = d__ + e;
00270 
00271 /*     Check for zero data. */
00272 
00273     if (trace == 0.) {
00274         z__[(*n << 1) - 1] = 0.;
00275         return 0;
00276     }
00277 
00278 /*     Check whether the machine is IEEE conformable. */
00279 
00280     ieee = ilaenv_(&c__10, "DLASQ2", "N", &c__1, &c__2, &c__3, &c__4) == 1 && ilaenv_(&c__11, "DLASQ2", "N", &c__1, &c__2, 
00281              &c__3, &c__4) == 1;
00282 
00283 /*     Rearrange data for locality: Z=(q1,qq1,e1,ee1,q2,qq2,e2,ee2,...). */
00284 
00285     for (k = *n << 1; k >= 2; k += -2) {
00286         z__[k * 2] = 0.;
00287         z__[(k << 1) - 1] = z__[k];
00288         z__[(k << 1) - 2] = 0.;
00289         z__[(k << 1) - 3] = z__[k - 1];
00290 /* L30: */
00291     }
00292 
00293     i0 = 1;
00294     n0 = *n;
00295 
00296 /*     Reverse the qd-array, if warranted. */
00297 
00298     if (z__[(i0 << 2) - 3] * 1.5 < z__[(n0 << 2) - 3]) {
00299         ipn4 = i0 + n0 << 2;
00300         i__1 = i0 + n0 - 1 << 1;
00301         for (i4 = i0 << 2; i4 <= i__1; i4 += 4) {
00302             temp = z__[i4 - 3];
00303             z__[i4 - 3] = z__[ipn4 - i4 - 3];
00304             z__[ipn4 - i4 - 3] = temp;
00305             temp = z__[i4 - 1];
00306             z__[i4 - 1] = z__[ipn4 - i4 - 5];
00307             z__[ipn4 - i4 - 5] = temp;
00308 /* L40: */
00309         }
00310     }
00311 
00312 /*     Initial split checking via dqd and Li's test. */
00313 
00314     pp = 0;
00315 
00316     for (k = 1; k <= 2; ++k) {
00317 
00318         d__ = z__[(n0 << 2) + pp - 3];
00319         i__1 = (i0 << 2) + pp;
00320         for (i4 = (n0 - 1 << 2) + pp; i4 >= i__1; i4 += -4) {
00321             if (z__[i4 - 1] <= tol2 * d__) {
00322                 z__[i4 - 1] = -0.;
00323                 d__ = z__[i4 - 3];
00324             } else {
00325                 d__ = z__[i4 - 3] * (d__ / (d__ + z__[i4 - 1]));
00326             }
00327 /* L50: */
00328         }
00329 
00330 /*        dqd maps Z to ZZ plus Li's test. */
00331 
00332         emin = z__[(i0 << 2) + pp + 1];
00333         d__ = z__[(i0 << 2) + pp - 3];
00334         i__1 = (n0 - 1 << 2) + pp;
00335         for (i4 = (i0 << 2) + pp; i4 <= i__1; i4 += 4) {
00336             z__[i4 - (pp << 1) - 2] = d__ + z__[i4 - 1];
00337             if (z__[i4 - 1] <= tol2 * d__) {
00338                 z__[i4 - 1] = -0.;
00339                 z__[i4 - (pp << 1) - 2] = d__;
00340                 z__[i4 - (pp << 1)] = 0.;
00341                 d__ = z__[i4 + 1];
00342             } else if (safmin * z__[i4 + 1] < z__[i4 - (pp << 1) - 2] && 
00343                     safmin * z__[i4 - (pp << 1) - 2] < z__[i4 + 1]) {
00344                 temp = z__[i4 + 1] / z__[i4 - (pp << 1) - 2];
00345                 z__[i4 - (pp << 1)] = z__[i4 - 1] * temp;
00346                 d__ *= temp;
00347             } else {
00348                 z__[i4 - (pp << 1)] = z__[i4 + 1] * (z__[i4 - 1] / z__[i4 - (
00349                         pp << 1) - 2]);
00350                 d__ = z__[i4 + 1] * (d__ / z__[i4 - (pp << 1) - 2]);
00351             }
00352 /* Computing MIN */
00353             d__1 = emin, d__2 = z__[i4 - (pp << 1)];
00354             emin = min(d__1,d__2);
00355 /* L60: */
00356         }
00357         z__[(n0 << 2) - pp - 2] = d__;
00358 
00359 /*        Now find qmax. */
00360 
00361         qmax = z__[(i0 << 2) - pp - 2];
00362         i__1 = (n0 << 2) - pp - 2;
00363         for (i4 = (i0 << 2) - pp + 2; i4 <= i__1; i4 += 4) {
00364 /* Computing MAX */
00365             d__1 = qmax, d__2 = z__[i4];
00366             qmax = max(d__1,d__2);
00367 /* L70: */
00368         }
00369 
00370 /*        Prepare for the next iteration on K. */
00371 
00372         pp = 1 - pp;
00373 /* L80: */
00374     }
00375 
00376 /*     Initialise variables to pass to DLASQ3. */
00377 
00378     ttype = 0;
00379     dmin1 = 0.;
00380     dmin2 = 0.;
00381     dn = 0.;
00382     dn1 = 0.;
00383     dn2 = 0.;
00384     g = 0.;
00385     tau = 0.;
00386 
00387     iter = 2;
00388     nfail = 0;
00389     ndiv = n0 - i0 << 1;
00390 
00391     i__1 = *n + 1;
00392     for (iwhila = 1; iwhila <= i__1; ++iwhila) {
00393         if (n0 < 1) {
00394             goto L170;
00395         }
00396 
00397 /*        While array unfinished do */
00398 
00399 /*        E(N0) holds the value of SIGMA when submatrix in I0:N0 */
00400 /*        splits from the rest of the array, but is negated. */
00401 
00402         desig = 0.;
00403         if (n0 == *n) {
00404             sigma = 0.;
00405         } else {
00406             sigma = -z__[(n0 << 2) - 1];
00407         }
00408         if (sigma < 0.) {
00409             *info = 1;
00410             return 0;
00411         }
00412 
00413 /*        Find last unreduced submatrix's top index I0, find QMAX and */
00414 /*        EMIN. Find Gershgorin-type bound if Q's much greater than E's. */
00415 
00416         emax = 0.;
00417         if (n0 > i0) {
00418             emin = (d__1 = z__[(n0 << 2) - 5], abs(d__1));
00419         } else {
00420             emin = 0.;
00421         }
00422         qmin = z__[(n0 << 2) - 3];
00423         qmax = qmin;
00424         for (i4 = n0 << 2; i4 >= 8; i4 += -4) {
00425             if (z__[i4 - 5] <= 0.) {
00426                 goto L100;
00427             }
00428             if (qmin >= emax * 4.) {
00429 /* Computing MIN */
00430                 d__1 = qmin, d__2 = z__[i4 - 3];
00431                 qmin = min(d__1,d__2);
00432 /* Computing MAX */
00433                 d__1 = emax, d__2 = z__[i4 - 5];
00434                 emax = max(d__1,d__2);
00435             }
00436 /* Computing MAX */
00437             d__1 = qmax, d__2 = z__[i4 - 7] + z__[i4 - 5];
00438             qmax = max(d__1,d__2);
00439 /* Computing MIN */
00440             d__1 = emin, d__2 = z__[i4 - 5];
00441             emin = min(d__1,d__2);
00442 /* L90: */
00443         }
00444         i4 = 4;
00445 
00446 L100:
00447         i0 = i4 / 4;
00448         pp = 0;
00449 
00450         if (n0 - i0 > 1) {
00451             dee = z__[(i0 << 2) - 3];
00452             deemin = dee;
00453             kmin = i0;
00454             i__2 = (n0 << 2) - 3;
00455             for (i4 = (i0 << 2) + 1; i4 <= i__2; i4 += 4) {
00456                 dee = z__[i4] * (dee / (dee + z__[i4 - 2]));
00457                 if (dee <= deemin) {
00458                     deemin = dee;
00459                     kmin = (i4 + 3) / 4;
00460                 }
00461 /* L110: */
00462             }
00463             if (kmin - i0 << 1 < n0 - kmin && deemin <= z__[(n0 << 2) - 3] * 
00464                     .5) {
00465                 ipn4 = i0 + n0 << 2;
00466                 pp = 2;
00467                 i__2 = i0 + n0 - 1 << 1;
00468                 for (i4 = i0 << 2; i4 <= i__2; i4 += 4) {
00469                     temp = z__[i4 - 3];
00470                     z__[i4 - 3] = z__[ipn4 - i4 - 3];
00471                     z__[ipn4 - i4 - 3] = temp;
00472                     temp = z__[i4 - 2];
00473                     z__[i4 - 2] = z__[ipn4 - i4 - 2];
00474                     z__[ipn4 - i4 - 2] = temp;
00475                     temp = z__[i4 - 1];
00476                     z__[i4 - 1] = z__[ipn4 - i4 - 5];
00477                     z__[ipn4 - i4 - 5] = temp;
00478                     temp = z__[i4];
00479                     z__[i4] = z__[ipn4 - i4 - 4];
00480                     z__[ipn4 - i4 - 4] = temp;
00481 /* L120: */
00482                 }
00483             }
00484         }
00485 
00486 /*        Put -(initial shift) into DMIN. */
00487 
00488 /* Computing MAX */
00489         d__1 = 0., d__2 = qmin - sqrt(qmin) * 2. * sqrt(emax);
00490         dmin__ = -max(d__1,d__2);
00491 
00492 /*        Now I0:N0 is unreduced. */
00493 /*        PP = 0 for ping, PP = 1 for pong. */
00494 /*        PP = 2 indicates that flipping was applied to the Z array and */
00495 /*               and that the tests for deflation upon entry in DLASQ3 */
00496 /*               should not be performed. */
00497 
00498         nbig = (n0 - i0 + 1) * 30;
00499         i__2 = nbig;
00500         for (iwhilb = 1; iwhilb <= i__2; ++iwhilb) {
00501             if (i0 > n0) {
00502                 goto L150;
00503             }
00504 
00505 /*           While submatrix unfinished take a good dqds step. */
00506 
00507             dlasq3_(&i0, &n0, &z__[1], &pp, &dmin__, &sigma, &desig, &qmax, &
00508                     nfail, &iter, &ndiv, &ieee, &ttype, &dmin1, &dmin2, &dn, &
00509                     dn1, &dn2, &g, &tau);
00510 
00511             pp = 1 - pp;
00512 
00513 /*           When EMIN is very small check for splits. */
00514 
00515             if (pp == 0 && n0 - i0 >= 3) {
00516                 if (z__[n0 * 4] <= tol2 * qmax || z__[(n0 << 2) - 1] <= tol2 *
00517                          sigma) {
00518                     splt = i0 - 1;
00519                     qmax = z__[(i0 << 2) - 3];
00520                     emin = z__[(i0 << 2) - 1];
00521                     oldemn = z__[i0 * 4];
00522                     i__3 = n0 - 3 << 2;
00523                     for (i4 = i0 << 2; i4 <= i__3; i4 += 4) {
00524                         if (z__[i4] <= tol2 * z__[i4 - 3] || z__[i4 - 1] <= 
00525                                 tol2 * sigma) {
00526                             z__[i4 - 1] = -sigma;
00527                             splt = i4 / 4;
00528                             qmax = 0.;
00529                             emin = z__[i4 + 3];
00530                             oldemn = z__[i4 + 4];
00531                         } else {
00532 /* Computing MAX */
00533                             d__1 = qmax, d__2 = z__[i4 + 1];
00534                             qmax = max(d__1,d__2);
00535 /* Computing MIN */
00536                             d__1 = emin, d__2 = z__[i4 - 1];
00537                             emin = min(d__1,d__2);
00538 /* Computing MIN */
00539                             d__1 = oldemn, d__2 = z__[i4];
00540                             oldemn = min(d__1,d__2);
00541                         }
00542 /* L130: */
00543                     }
00544                     z__[(n0 << 2) - 1] = emin;
00545                     z__[n0 * 4] = oldemn;
00546                     i0 = splt + 1;
00547                 }
00548             }
00549 
00550 /* L140: */
00551         }
00552 
00553         *info = 2;
00554         return 0;
00555 
00556 /*        end IWHILB */
00557 
00558 L150:
00559 
00560 /* L160: */
00561         ;
00562     }
00563 
00564     *info = 3;
00565     return 0;
00566 
00567 /*     end IWHILA */
00568 
00569 L170:
00570 
00571 /*     Move q's to the front. */
00572 
00573     i__1 = *n;
00574     for (k = 2; k <= i__1; ++k) {
00575         z__[k] = z__[(k << 2) - 3];
00576 /* L180: */
00577     }
00578 
00579 /*     Sort and compute sum of eigenvalues. */
00580 
00581     dlasrt_("D", n, &z__[1], &iinfo);
00582 
00583     e = 0.;
00584     for (k = *n; k >= 1; --k) {
00585         e += z__[k];
00586 /* L190: */
00587     }
00588 
00589 /*     Store trace, sum(eigenvalues) and information on performance. */
00590 
00591     z__[(*n << 1) + 1] = trace;
00592     z__[(*n << 1) + 2] = e;
00593     z__[(*n << 1) + 3] = (doublereal) iter;
00594 /* Computing 2nd power */
00595     i__1 = *n;
00596     z__[(*n << 1) + 4] = (doublereal) ndiv / (doublereal) (i__1 * i__1);
00597     z__[(*n << 1) + 5] = nfail * 100. / (doublereal) iter;
00598     return 0;
00599 
00600 /*     End of DLASQ2 */
00601 
00602 } /* dlasq2_ */


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