zsyequb.c
Go to the documentation of this file.
00001 /* zsyequb.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 
00020 /* Subroutine */ int zsyequb_(char *uplo, integer *n, doublecomplex *a, 
00021         integer *lda, doublereal *s, doublereal *scond, doublereal *amax, 
00022         doublecomplex *work, integer *info)
00023 {
00024     /* System generated locals */
00025     integer a_dim1, a_offset, i__1, i__2, i__3, i__4, i__5;
00026     doublereal d__1, d__2, d__3, d__4;
00027     doublecomplex z__1, z__2, z__3, z__4;
00028 
00029     /* Builtin functions */
00030     double d_imag(doublecomplex *), sqrt(doublereal), log(doublereal), pow_di(
00031             doublereal *, integer *);
00032 
00033     /* Local variables */
00034     doublereal d__;
00035     integer i__, j;
00036     doublereal t, u, c0, c1, c2, si;
00037     logical up;
00038     doublereal avg, std, tol, base;
00039     integer iter;
00040     doublereal smin, smax, scale;
00041     extern logical lsame_(char *, char *);
00042     doublereal sumsq;
00043     extern doublereal dlamch_(char *);
00044     extern /* Subroutine */ int xerbla_(char *, integer *);
00045     doublereal bignum, smlnum;
00046     extern /* Subroutine */ int zlassq_(integer *, doublecomplex *, integer *, 
00047              doublereal *, doublereal *);
00048 
00049 
00050 /*     -- LAPACK routine (version 3.2)                                 -- */
00051 /*     -- Contributed by James Demmel, Deaglan Halligan, Yozo Hida and -- */
00052 /*     -- Jason Riedy of Univ. of California Berkeley.                 -- */
00053 /*     -- November 2008                                                -- */
00054 
00055 /*     -- LAPACK is a software package provided by Univ. of Tennessee, -- */
00056 /*     -- Univ. of California Berkeley and NAG Ltd.                    -- */
00057 
00058 /*     .. */
00059 /*     .. Scalar Arguments .. */
00060 /*     .. */
00061 /*     .. Array Arguments .. */
00062 /*     .. */
00063 
00064 /*  Purpose */
00065 /*  ======= */
00066 
00067 /*  ZSYEQUB computes row and column scalings intended to equilibrate a */
00068 /*  symmetric matrix A and reduce its condition number */
00069 /*  (with respect to the two-norm).  S contains the scale factors, */
00070 /*  S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with */
00071 /*  elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal.  This */
00072 /*  choice of S puts the condition number of B within a factor N of the */
00073 /*  smallest possible condition number over all possible diagonal */
00074 /*  scalings. */
00075 
00076 /*  Arguments */
00077 /*  ========= */
00078 
00079 /*  N       (input) INTEGER */
00080 /*          The order of the matrix A.  N >= 0. */
00081 
00082 /*  A       (input) COMPLEX*16 array, dimension (LDA,N) */
00083 /*          The N-by-N symmetric matrix whose scaling */
00084 /*          factors are to be computed.  Only the diagonal elements of A */
00085 /*          are referenced. */
00086 
00087 /*  LDA     (input) INTEGER */
00088 /*          The leading dimension of the array A.  LDA >= max(1,N). */
00089 
00090 /*  S       (output) DOUBLE PRECISION array, dimension (N) */
00091 /*          If INFO = 0, S contains the scale factors for A. */
00092 
00093 /*  SCOND   (output) DOUBLE PRECISION */
00094 /*          If INFO = 0, S contains the ratio of the smallest S(i) to */
00095 /*          the largest S(i).  If SCOND >= 0.1 and AMAX is neither too */
00096 /*          large nor too small, it is not worth scaling by S. */
00097 
00098 /*  AMAX    (output) DOUBLE PRECISION */
00099 /*          Absolute value of largest matrix element.  If AMAX is very */
00100 /*          close to overflow or very close to underflow, the matrix */
00101 /*          should be scaled. */
00102 /*  INFO    (output) INTEGER */
00103 /*          = 0:  successful exit */
00104 /*          < 0:  if INFO = -i, the i-th argument had an illegal value */
00105 /*          > 0:  if INFO = i, the i-th diagonal element is nonpositive. */
00106 
00107 /*  Further Details */
00108 /*  ======= ======= */
00109 
00110 /*  Reference: Livne, O.E. and Golub, G.H., "Scaling by Binormalization", */
00111 /*  Numerical Algorithms, vol. 35, no. 1, pp. 97-120, January 2004. */
00112 /*  DOI 10.1023/B:NUMA.0000016606.32820.69 */
00113 /*  Tech report version: http://ruready.utah.edu/archive/papers/bin.pdf */
00114 
00115 /*  ===================================================================== */
00116 
00117 /*     .. Parameters .. */
00118 /*     .. */
00119 /*     .. Local Scalars .. */
00120 /*     .. */
00121 /*     .. External Functions .. */
00122 /*     .. */
00123 /*     .. External Subroutines .. */
00124 /*     .. */
00125 /*     .. Statement Functions .. */
00126 /*     .. */
00127 /*     Statement Function Definitions */
00128 /*     .. */
00129 /*     .. Executable Statements .. */
00130 
00131 /*     Test the input parameters. */
00132 
00133     /* Parameter adjustments */
00134     a_dim1 = *lda;
00135     a_offset = 1 + a_dim1;
00136     a -= a_offset;
00137     --s;
00138     --work;
00139 
00140     /* Function Body */
00141     *info = 0;
00142     if (! (lsame_(uplo, "U") || lsame_(uplo, "L"))) {
00143         *info = -1;
00144     } else if (*n < 0) {
00145         *info = -2;
00146     } else if (*lda < max(1,*n)) {
00147         *info = -4;
00148     }
00149     if (*info != 0) {
00150         i__1 = -(*info);
00151         xerbla_("ZSYEQUB", &i__1);
00152         return 0;
00153     }
00154     up = lsame_(uplo, "U");
00155     *amax = 0.;
00156 
00157 /*     Quick return if possible. */
00158 
00159     if (*n == 0) {
00160         *scond = 1.;
00161         return 0;
00162     }
00163     i__1 = *n;
00164     for (i__ = 1; i__ <= i__1; ++i__) {
00165         s[i__] = 0.;
00166     }
00167     *amax = 0.;
00168     if (up) {
00169         i__1 = *n;
00170         for (j = 1; j <= i__1; ++j) {
00171             i__2 = j - 1;
00172             for (i__ = 1; i__ <= i__2; ++i__) {
00173 /* Computing MAX */
00174                 i__3 = i__ + j * a_dim1;
00175                 d__3 = s[i__], d__4 = (d__1 = a[i__3].r, abs(d__1)) + (d__2 = 
00176                         d_imag(&a[i__ + j * a_dim1]), abs(d__2));
00177                 s[i__] = max(d__3,d__4);
00178 /* Computing MAX */
00179                 i__3 = i__ + j * a_dim1;
00180                 d__3 = s[j], d__4 = (d__1 = a[i__3].r, abs(d__1)) + (d__2 = 
00181                         d_imag(&a[i__ + j * a_dim1]), abs(d__2));
00182                 s[j] = max(d__3,d__4);
00183 /* Computing MAX */
00184                 i__3 = i__ + j * a_dim1;
00185                 d__3 = *amax, d__4 = (d__1 = a[i__3].r, abs(d__1)) + (d__2 = 
00186                         d_imag(&a[i__ + j * a_dim1]), abs(d__2));
00187                 *amax = max(d__3,d__4);
00188             }
00189 /* Computing MAX */
00190             i__2 = j + j * a_dim1;
00191             d__3 = s[j], d__4 = (d__1 = a[i__2].r, abs(d__1)) + (d__2 = 
00192                     d_imag(&a[j + j * a_dim1]), abs(d__2));
00193             s[j] = max(d__3,d__4);
00194 /* Computing MAX */
00195             i__2 = j + j * a_dim1;
00196             d__3 = *amax, d__4 = (d__1 = a[i__2].r, abs(d__1)) + (d__2 = 
00197                     d_imag(&a[j + j * a_dim1]), abs(d__2));
00198             *amax = max(d__3,d__4);
00199         }
00200     } else {
00201         i__1 = *n;
00202         for (j = 1; j <= i__1; ++j) {
00203 /* Computing MAX */
00204             i__2 = j + j * a_dim1;
00205             d__3 = s[j], d__4 = (d__1 = a[i__2].r, abs(d__1)) + (d__2 = 
00206                     d_imag(&a[j + j * a_dim1]), abs(d__2));
00207             s[j] = max(d__3,d__4);
00208 /* Computing MAX */
00209             i__2 = j + j * a_dim1;
00210             d__3 = *amax, d__4 = (d__1 = a[i__2].r, abs(d__1)) + (d__2 = 
00211                     d_imag(&a[j + j * a_dim1]), abs(d__2));
00212             *amax = max(d__3,d__4);
00213             i__2 = *n;
00214             for (i__ = j + 1; i__ <= i__2; ++i__) {
00215 /* Computing MAX */
00216                 i__3 = i__ + j * a_dim1;
00217                 d__3 = s[i__], d__4 = (d__1 = a[i__3].r, abs(d__1)) + (d__2 = 
00218                         d_imag(&a[i__ + j * a_dim1]), abs(d__2));
00219                 s[i__] = max(d__3,d__4);
00220 /* Computing MAX */
00221                 i__3 = i__ + j * a_dim1;
00222                 d__3 = s[j], d__4 = (d__1 = a[i__3].r, abs(d__1)) + (d__2 = 
00223                         d_imag(&a[i__ + j * a_dim1]), abs(d__2));
00224                 s[j] = max(d__3,d__4);
00225 /* Computing MAX */
00226                 i__3 = i__ + j * a_dim1;
00227                 d__3 = *amax, d__4 = (d__1 = a[i__3].r, abs(d__1)) + (d__2 = 
00228                         d_imag(&a[i__ + j * a_dim1]), abs(d__2));
00229                 *amax = max(d__3,d__4);
00230             }
00231         }
00232     }
00233     i__1 = *n;
00234     for (j = 1; j <= i__1; ++j) {
00235         s[j] = 1. / s[j];
00236     }
00237     tol = 1. / sqrt(*n * 2.);
00238     for (iter = 1; iter <= 100; ++iter) {
00239         scale = 0.;
00240         sumsq = 0.;
00241 /*       beta = |A|s */
00242         i__1 = *n;
00243         for (i__ = 1; i__ <= i__1; ++i__) {
00244             i__2 = i__;
00245             work[i__2].r = 0., work[i__2].i = 0.;
00246         }
00247         if (up) {
00248             i__1 = *n;
00249             for (j = 1; j <= i__1; ++j) {
00250                 i__2 = j - 1;
00251                 for (i__ = 1; i__ <= i__2; ++i__) {
00252                     i__3 = i__ + j * a_dim1;
00253                     t = (d__1 = a[i__3].r, abs(d__1)) + (d__2 = d_imag(&a[i__ 
00254                             + j * a_dim1]), abs(d__2));
00255                     i__3 = i__;
00256                     i__4 = i__;
00257                     i__5 = i__ + j * a_dim1;
00258                     d__3 = ((d__1 = a[i__5].r, abs(d__1)) + (d__2 = d_imag(&a[
00259                             i__ + j * a_dim1]), abs(d__2))) * s[j];
00260                     z__1.r = work[i__4].r + d__3, z__1.i = work[i__4].i;
00261                     work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00262                     i__3 = j;
00263                     i__4 = j;
00264                     i__5 = i__ + j * a_dim1;
00265                     d__3 = ((d__1 = a[i__5].r, abs(d__1)) + (d__2 = d_imag(&a[
00266                             i__ + j * a_dim1]), abs(d__2))) * s[i__];
00267                     z__1.r = work[i__4].r + d__3, z__1.i = work[i__4].i;
00268                     work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00269                 }
00270                 i__2 = j;
00271                 i__3 = j;
00272                 i__4 = j + j * a_dim1;
00273                 d__3 = ((d__1 = a[i__4].r, abs(d__1)) + (d__2 = d_imag(&a[j + 
00274                         j * a_dim1]), abs(d__2))) * s[j];
00275                 z__1.r = work[i__3].r + d__3, z__1.i = work[i__3].i;
00276                 work[i__2].r = z__1.r, work[i__2].i = z__1.i;
00277             }
00278         } else {
00279             i__1 = *n;
00280             for (j = 1; j <= i__1; ++j) {
00281                 i__2 = j;
00282                 i__3 = j;
00283                 i__4 = j + j * a_dim1;
00284                 d__3 = ((d__1 = a[i__4].r, abs(d__1)) + (d__2 = d_imag(&a[j + 
00285                         j * a_dim1]), abs(d__2))) * s[j];
00286                 z__1.r = work[i__3].r + d__3, z__1.i = work[i__3].i;
00287                 work[i__2].r = z__1.r, work[i__2].i = z__1.i;
00288                 i__2 = *n;
00289                 for (i__ = j + 1; i__ <= i__2; ++i__) {
00290                     i__3 = i__ + j * a_dim1;
00291                     t = (d__1 = a[i__3].r, abs(d__1)) + (d__2 = d_imag(&a[i__ 
00292                             + j * a_dim1]), abs(d__2));
00293                     i__3 = i__;
00294                     i__4 = i__;
00295                     i__5 = i__ + j * a_dim1;
00296                     d__3 = ((d__1 = a[i__5].r, abs(d__1)) + (d__2 = d_imag(&a[
00297                             i__ + j * a_dim1]), abs(d__2))) * s[j];
00298                     z__1.r = work[i__4].r + d__3, z__1.i = work[i__4].i;
00299                     work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00300                     i__3 = j;
00301                     i__4 = j;
00302                     i__5 = i__ + j * a_dim1;
00303                     d__3 = ((d__1 = a[i__5].r, abs(d__1)) + (d__2 = d_imag(&a[
00304                             i__ + j * a_dim1]), abs(d__2))) * s[i__];
00305                     z__1.r = work[i__4].r + d__3, z__1.i = work[i__4].i;
00306                     work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00307                 }
00308             }
00309         }
00310 /*       avg = s^T beta / n */
00311         avg = 0.;
00312         i__1 = *n;
00313         for (i__ = 1; i__ <= i__1; ++i__) {
00314             i__2 = i__;
00315             i__3 = i__;
00316             z__2.r = s[i__2] * work[i__3].r, z__2.i = s[i__2] * work[i__3].i;
00317             z__1.r = avg + z__2.r, z__1.i = z__2.i;
00318             avg = z__1.r;
00319         }
00320         avg /= *n;
00321         std = 0.;
00322         i__1 = *n << 1;
00323         for (i__ = *n + 1; i__ <= i__1; ++i__) {
00324             i__2 = i__;
00325             i__3 = i__ - *n;
00326             i__4 = i__ - *n;
00327             z__2.r = s[i__3] * work[i__4].r, z__2.i = s[i__3] * work[i__4].i;
00328             z__1.r = z__2.r - avg, z__1.i = z__2.i;
00329             work[i__2].r = z__1.r, work[i__2].i = z__1.i;
00330         }
00331         zlassq_(n, &work[*n + 1], &c__1, &scale, &sumsq);
00332         std = scale * sqrt(sumsq / *n);
00333         if (std < tol * avg) {
00334             goto L999;
00335         }
00336         i__1 = *n;
00337         for (i__ = 1; i__ <= i__1; ++i__) {
00338             i__2 = i__ + i__ * a_dim1;
00339             t = (d__1 = a[i__2].r, abs(d__1)) + (d__2 = d_imag(&a[i__ + i__ * 
00340                     a_dim1]), abs(d__2));
00341             si = s[i__];
00342             c2 = (*n - 1) * t;
00343             i__2 = *n - 2;
00344             i__3 = i__;
00345             d__1 = t * si;
00346             z__2.r = work[i__3].r - d__1, z__2.i = work[i__3].i;
00347             d__2 = (doublereal) i__2;
00348             z__1.r = d__2 * z__2.r, z__1.i = d__2 * z__2.i;
00349             c1 = z__1.r;
00350             d__1 = -(t * si) * si;
00351             i__2 = i__;
00352             d__2 = 2.;
00353             z__4.r = d__2 * work[i__2].r, z__4.i = d__2 * work[i__2].i;
00354             z__3.r = si * z__4.r, z__3.i = si * z__4.i;
00355             z__2.r = d__1 + z__3.r, z__2.i = z__3.i;
00356             d__3 = *n * avg;
00357             z__1.r = z__2.r - d__3, z__1.i = z__2.i;
00358             c0 = z__1.r;
00359             d__ = c1 * c1 - c0 * 4 * c2;
00360             if (d__ <= 0.) {
00361                 *info = -1;
00362                 return 0;
00363             }
00364             si = c0 * -2 / (c1 + sqrt(d__));
00365             d__ = si - s[i__];
00366             u = 0.;
00367             if (up) {
00368                 i__2 = i__;
00369                 for (j = 1; j <= i__2; ++j) {
00370                     i__3 = j + i__ * a_dim1;
00371                     t = (d__1 = a[i__3].r, abs(d__1)) + (d__2 = d_imag(&a[j + 
00372                             i__ * a_dim1]), abs(d__2));
00373                     u += s[j] * t;
00374                     i__3 = j;
00375                     i__4 = j;
00376                     d__1 = d__ * t;
00377                     z__1.r = work[i__4].r + d__1, z__1.i = work[i__4].i;
00378                     work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00379                 }
00380                 i__2 = *n;
00381                 for (j = i__ + 1; j <= i__2; ++j) {
00382                     i__3 = i__ + j * a_dim1;
00383                     t = (d__1 = a[i__3].r, abs(d__1)) + (d__2 = d_imag(&a[i__ 
00384                             + j * a_dim1]), abs(d__2));
00385                     u += s[j] * t;
00386                     i__3 = j;
00387                     i__4 = j;
00388                     d__1 = d__ * t;
00389                     z__1.r = work[i__4].r + d__1, z__1.i = work[i__4].i;
00390                     work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00391                 }
00392             } else {
00393                 i__2 = i__;
00394                 for (j = 1; j <= i__2; ++j) {
00395                     i__3 = i__ + j * a_dim1;
00396                     t = (d__1 = a[i__3].r, abs(d__1)) + (d__2 = d_imag(&a[i__ 
00397                             + j * a_dim1]), abs(d__2));
00398                     u += s[j] * t;
00399                     i__3 = j;
00400                     i__4 = j;
00401                     d__1 = d__ * t;
00402                     z__1.r = work[i__4].r + d__1, z__1.i = work[i__4].i;
00403                     work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00404                 }
00405                 i__2 = *n;
00406                 for (j = i__ + 1; j <= i__2; ++j) {
00407                     i__3 = j + i__ * a_dim1;
00408                     t = (d__1 = a[i__3].r, abs(d__1)) + (d__2 = d_imag(&a[j + 
00409                             i__ * a_dim1]), abs(d__2));
00410                     u += s[j] * t;
00411                     i__3 = j;
00412                     i__4 = j;
00413                     d__1 = d__ * t;
00414                     z__1.r = work[i__4].r + d__1, z__1.i = work[i__4].i;
00415                     work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00416                 }
00417             }
00418             i__2 = i__;
00419             z__4.r = u + work[i__2].r, z__4.i = work[i__2].i;
00420             z__3.r = d__ * z__4.r, z__3.i = d__ * z__4.i;
00421             d__1 = (doublereal) (*n);
00422             z__2.r = z__3.r / d__1, z__2.i = z__3.i / d__1;
00423             z__1.r = avg + z__2.r, z__1.i = z__2.i;
00424             avg = z__1.r;
00425             s[i__] = si;
00426         }
00427     }
00428 L999:
00429     smlnum = dlamch_("SAFEMIN");
00430     bignum = 1. / smlnum;
00431     smin = bignum;
00432     smax = 0.;
00433     t = 1. / sqrt(avg);
00434     base = dlamch_("B");
00435     u = 1. / log(base);
00436     i__1 = *n;
00437     for (i__ = 1; i__ <= i__1; ++i__) {
00438         i__2 = (integer) (u * log(s[i__] * t));
00439         s[i__] = pow_di(&base, &i__2);
00440 /* Computing MIN */
00441         d__1 = smin, d__2 = s[i__];
00442         smin = min(d__1,d__2);
00443 /* Computing MAX */
00444         d__1 = smax, d__2 = s[i__];
00445         smax = max(d__1,d__2);
00446     }
00447     *scond = max(smin,smlnum) / min(smax,bignum);
00448 
00449     return 0;
00450 } /* zsyequb_ */


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