zheequb.c
Go to the documentation of this file.
00001 /* zheequb.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 zheequb_(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 /*  ===================================================================== */
00108 
00109 /*     .. Parameters .. */
00110 /*     .. */
00111 /*     .. Local Scalars .. */
00112 /*     .. */
00113 /*     .. External Functions .. */
00114 /*     .. */
00115 /*     .. External Subroutines .. */
00116 /*     .. */
00117 /*     .. Statement Functions .. */
00118 /*     .. */
00119 /*     .. Statement Function Definitions .. */
00120 
00121 /*     Test input parameters. */
00122 
00123     /* Parameter adjustments */
00124     a_dim1 = *lda;
00125     a_offset = 1 + a_dim1;
00126     a -= a_offset;
00127     --s;
00128     --work;
00129 
00130     /* Function Body */
00131     *info = 0;
00132     if (! (lsame_(uplo, "U") || lsame_(uplo, "L"))) {
00133         *info = -1;
00134     } else if (*n < 0) {
00135         *info = -2;
00136     } else if (*lda < max(1,*n)) {
00137         *info = -4;
00138     }
00139     if (*info != 0) {
00140         i__1 = -(*info);
00141         xerbla_("ZHEEQUB", &i__1);
00142         return 0;
00143     }
00144     up = lsame_(uplo, "U");
00145     *amax = 0.;
00146 
00147 /*     Quick return if possible. */
00148 
00149     if (*n == 0) {
00150         *scond = 1.;
00151         return 0;
00152     }
00153     i__1 = *n;
00154     for (i__ = 1; i__ <= i__1; ++i__) {
00155         s[i__] = 0.;
00156     }
00157     *amax = 0.;
00158     if (up) {
00159         i__1 = *n;
00160         for (j = 1; j <= i__1; ++j) {
00161             i__2 = j - 1;
00162             for (i__ = 1; i__ <= i__2; ++i__) {
00163 /* Computing MAX */
00164                 i__3 = i__ + j * a_dim1;
00165                 d__3 = s[i__], d__4 = (d__1 = a[i__3].r, abs(d__1)) + (d__2 = 
00166                         d_imag(&a[i__ + j * a_dim1]), abs(d__2));
00167                 s[i__] = max(d__3,d__4);
00168 /* Computing MAX */
00169                 i__3 = i__ + j * a_dim1;
00170                 d__3 = s[j], d__4 = (d__1 = a[i__3].r, abs(d__1)) + (d__2 = 
00171                         d_imag(&a[i__ + j * a_dim1]), abs(d__2));
00172                 s[j] = max(d__3,d__4);
00173 /* Computing MAX */
00174                 i__3 = i__ + j * a_dim1;
00175                 d__3 = *amax, 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                 *amax = max(d__3,d__4);
00178             }
00179 /* Computing MAX */
00180             i__2 = j + j * a_dim1;
00181             d__3 = s[j], d__4 = (d__1 = a[i__2].r, abs(d__1)) + (d__2 = 
00182                     d_imag(&a[j + j * a_dim1]), abs(d__2));
00183             s[j] = max(d__3,d__4);
00184 /* Computing MAX */
00185             i__2 = j + j * a_dim1;
00186             d__3 = *amax, d__4 = (d__1 = a[i__2].r, abs(d__1)) + (d__2 = 
00187                     d_imag(&a[j + j * a_dim1]), abs(d__2));
00188             *amax = max(d__3,d__4);
00189         }
00190     } else {
00191         i__1 = *n;
00192         for (j = 1; j <= i__1; ++j) {
00193 /* Computing MAX */
00194             i__2 = j + j * a_dim1;
00195             d__3 = s[j], d__4 = (d__1 = a[i__2].r, abs(d__1)) + (d__2 = 
00196                     d_imag(&a[j + j * a_dim1]), abs(d__2));
00197             s[j] = max(d__3,d__4);
00198 /* Computing MAX */
00199             i__2 = j + j * a_dim1;
00200             d__3 = *amax, d__4 = (d__1 = a[i__2].r, abs(d__1)) + (d__2 = 
00201                     d_imag(&a[j + j * a_dim1]), abs(d__2));
00202             *amax = max(d__3,d__4);
00203             i__2 = *n;
00204             for (i__ = j + 1; i__ <= i__2; ++i__) {
00205 /* Computing MAX */
00206                 i__3 = i__ + j * a_dim1;
00207                 d__3 = s[i__], d__4 = (d__1 = a[i__3].r, abs(d__1)) + (d__2 = 
00208                         d_imag(&a[i__ + j * a_dim1]), abs(d__2));
00209                 s[i__] = max(d__3,d__4);
00210 /* Computing MAX */
00211                 i__3 = i__ + j * a_dim1;
00212                 d__3 = s[j], d__4 = (d__1 = a[i__3].r, abs(d__1)) + (d__2 = 
00213                         d_imag(&a[i__ + j * a_dim1]), abs(d__2));
00214                 s[j] = max(d__3,d__4);
00215 /* Computing MAX */
00216                 i__3 = i__ + j * a_dim1;
00217                 d__3 = *amax, 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                 *amax = max(d__3,d__4);
00220             }
00221         }
00222     }
00223     i__1 = *n;
00224     for (j = 1; j <= i__1; ++j) {
00225         s[j] = 1. / s[j];
00226     }
00227     tol = 1. / sqrt(*n * 2.);
00228     for (iter = 1; iter <= 100; ++iter) {
00229         scale = 0.;
00230         sumsq = 0.;
00231 /*       beta = |A|s */
00232         i__1 = *n;
00233         for (i__ = 1; i__ <= i__1; ++i__) {
00234             i__2 = i__;
00235             work[i__2].r = 0., work[i__2].i = 0.;
00236         }
00237         if (up) {
00238             i__1 = *n;
00239             for (j = 1; j <= i__1; ++j) {
00240                 i__2 = j - 1;
00241                 for (i__ = 1; i__ <= i__2; ++i__) {
00242                     i__3 = i__ + j * a_dim1;
00243                     t = (d__1 = a[i__3].r, abs(d__1)) + (d__2 = d_imag(&a[i__ 
00244                             + j * a_dim1]), abs(d__2));
00245                     i__3 = i__;
00246                     i__4 = i__;
00247                     i__5 = i__ + j * a_dim1;
00248                     d__3 = ((d__1 = a[i__5].r, abs(d__1)) + (d__2 = d_imag(&a[
00249                             i__ + j * a_dim1]), abs(d__2))) * s[j];
00250                     z__1.r = work[i__4].r + d__3, z__1.i = work[i__4].i;
00251                     work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00252                     i__3 = j;
00253                     i__4 = j;
00254                     i__5 = i__ + j * a_dim1;
00255                     d__3 = ((d__1 = a[i__5].r, abs(d__1)) + (d__2 = d_imag(&a[
00256                             i__ + j * a_dim1]), abs(d__2))) * s[i__];
00257                     z__1.r = work[i__4].r + d__3, z__1.i = work[i__4].i;
00258                     work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00259                 }
00260                 i__2 = j;
00261                 i__3 = j;
00262                 i__4 = j + j * a_dim1;
00263                 d__3 = ((d__1 = a[i__4].r, abs(d__1)) + (d__2 = d_imag(&a[j + 
00264                         j * a_dim1]), abs(d__2))) * s[j];
00265                 z__1.r = work[i__3].r + d__3, z__1.i = work[i__3].i;
00266                 work[i__2].r = z__1.r, work[i__2].i = z__1.i;
00267             }
00268         } else {
00269             i__1 = *n;
00270             for (j = 1; j <= i__1; ++j) {
00271                 i__2 = j;
00272                 i__3 = j;
00273                 i__4 = j + j * a_dim1;
00274                 d__3 = ((d__1 = a[i__4].r, abs(d__1)) + (d__2 = d_imag(&a[j + 
00275                         j * a_dim1]), abs(d__2))) * s[j];
00276                 z__1.r = work[i__3].r + d__3, z__1.i = work[i__3].i;
00277                 work[i__2].r = z__1.r, work[i__2].i = z__1.i;
00278                 i__2 = *n;
00279                 for (i__ = j + 1; i__ <= i__2; ++i__) {
00280                     i__3 = i__ + j * a_dim1;
00281                     t = (d__1 = a[i__3].r, abs(d__1)) + (d__2 = d_imag(&a[i__ 
00282                             + j * a_dim1]), abs(d__2));
00283                     i__3 = i__;
00284                     i__4 = i__;
00285                     i__5 = i__ + j * a_dim1;
00286                     d__3 = ((d__1 = a[i__5].r, abs(d__1)) + (d__2 = d_imag(&a[
00287                             i__ + j * a_dim1]), abs(d__2))) * s[j];
00288                     z__1.r = work[i__4].r + d__3, z__1.i = work[i__4].i;
00289                     work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00290                     i__3 = j;
00291                     i__4 = j;
00292                     i__5 = i__ + j * a_dim1;
00293                     d__3 = ((d__1 = a[i__5].r, abs(d__1)) + (d__2 = d_imag(&a[
00294                             i__ + j * a_dim1]), abs(d__2))) * s[i__];
00295                     z__1.r = work[i__4].r + d__3, z__1.i = work[i__4].i;
00296                     work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00297                 }
00298             }
00299         }
00300 /*       avg = s^T beta / n */
00301         avg = 0.;
00302         i__1 = *n;
00303         for (i__ = 1; i__ <= i__1; ++i__) {
00304             i__2 = i__;
00305             i__3 = i__;
00306             z__2.r = s[i__2] * work[i__3].r, z__2.i = s[i__2] * work[i__3].i;
00307             z__1.r = avg + z__2.r, z__1.i = z__2.i;
00308             avg = z__1.r;
00309         }
00310         avg /= *n;
00311         std = 0.;
00312         i__1 = *n * 3;
00313         for (i__ = (*n << 1) + 1; i__ <= i__1; ++i__) {
00314             i__2 = i__;
00315             i__3 = i__ - (*n << 1);
00316             i__4 = i__ - (*n << 1);
00317             z__2.r = s[i__3] * work[i__4].r, z__2.i = s[i__3] * work[i__4].i;
00318             z__1.r = z__2.r - avg, z__1.i = z__2.i;
00319             work[i__2].r = z__1.r, work[i__2].i = z__1.i;
00320         }
00321         zlassq_(n, &work[(*n << 1) + 1], &c__1, &scale, &sumsq);
00322         std = scale * sqrt(sumsq / *n);
00323         if (std < tol * avg) {
00324             goto L999;
00325         }
00326         i__1 = *n;
00327         for (i__ = 1; i__ <= i__1; ++i__) {
00328             i__2 = i__ + i__ * a_dim1;
00329             t = (d__1 = a[i__2].r, abs(d__1)) + (d__2 = d_imag(&a[i__ + i__ * 
00330                     a_dim1]), abs(d__2));
00331             si = s[i__];
00332             c2 = (*n - 1) * t;
00333             i__2 = *n - 2;
00334             i__3 = i__;
00335             d__1 = t * si;
00336             z__2.r = work[i__3].r - d__1, z__2.i = work[i__3].i;
00337             d__2 = (doublereal) i__2;
00338             z__1.r = d__2 * z__2.r, z__1.i = d__2 * z__2.i;
00339             c1 = z__1.r;
00340             d__1 = -(t * si) * si;
00341             i__2 = i__;
00342             d__2 = 2.;
00343             z__4.r = d__2 * work[i__2].r, z__4.i = d__2 * work[i__2].i;
00344             z__3.r = si * z__4.r, z__3.i = si * z__4.i;
00345             z__2.r = d__1 + z__3.r, z__2.i = z__3.i;
00346             d__3 = *n * avg;
00347             z__1.r = z__2.r - d__3, z__1.i = z__2.i;
00348             c0 = z__1.r;
00349             d__ = c1 * c1 - c0 * 4 * c2;
00350             if (d__ <= 0.) {
00351                 *info = -1;
00352                 return 0;
00353             }
00354             si = c0 * -2 / (c1 + sqrt(d__));
00355             d__ = si - s[i__];
00356             u = 0.;
00357             if (up) {
00358                 i__2 = i__;
00359                 for (j = 1; j <= i__2; ++j) {
00360                     i__3 = j + i__ * a_dim1;
00361                     t = (d__1 = a[i__3].r, abs(d__1)) + (d__2 = d_imag(&a[j + 
00362                             i__ * a_dim1]), abs(d__2));
00363                     u += s[j] * t;
00364                     i__3 = j;
00365                     i__4 = j;
00366                     d__1 = d__ * t;
00367                     z__1.r = work[i__4].r + d__1, z__1.i = work[i__4].i;
00368                     work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00369                 }
00370                 i__2 = *n;
00371                 for (j = i__ + 1; j <= i__2; ++j) {
00372                     i__3 = i__ + j * a_dim1;
00373                     t = (d__1 = a[i__3].r, abs(d__1)) + (d__2 = d_imag(&a[i__ 
00374                             + j * a_dim1]), abs(d__2));
00375                     u += s[j] * t;
00376                     i__3 = j;
00377                     i__4 = j;
00378                     d__1 = d__ * t;
00379                     z__1.r = work[i__4].r + d__1, z__1.i = work[i__4].i;
00380                     work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00381                 }
00382             } else {
00383                 i__2 = i__;
00384                 for (j = 1; j <= i__2; ++j) {
00385                     i__3 = i__ + j * a_dim1;
00386                     t = (d__1 = a[i__3].r, abs(d__1)) + (d__2 = d_imag(&a[i__ 
00387                             + j * a_dim1]), abs(d__2));
00388                     u += s[j] * t;
00389                     i__3 = j;
00390                     i__4 = j;
00391                     d__1 = d__ * t;
00392                     z__1.r = work[i__4].r + d__1, z__1.i = work[i__4].i;
00393                     work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00394                 }
00395                 i__2 = *n;
00396                 for (j = i__ + 1; j <= i__2; ++j) {
00397                     i__3 = j + i__ * a_dim1;
00398                     t = (d__1 = a[i__3].r, abs(d__1)) + (d__2 = d_imag(&a[j + 
00399                             i__ * a_dim1]), abs(d__2));
00400                     u += s[j] * t;
00401                     i__3 = j;
00402                     i__4 = j;
00403                     d__1 = d__ * t;
00404                     z__1.r = work[i__4].r + d__1, z__1.i = work[i__4].i;
00405                     work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00406                 }
00407             }
00408             i__2 = i__;
00409             z__4.r = u + work[i__2].r, z__4.i = work[i__2].i;
00410             z__3.r = d__ * z__4.r, z__3.i = d__ * z__4.i;
00411             d__1 = (doublereal) (*n);
00412             z__2.r = z__3.r / d__1, z__2.i = z__3.i / d__1;
00413             z__1.r = avg + z__2.r, z__1.i = z__2.i;
00414             avg = z__1.r;
00415             s[i__] = si;
00416         }
00417     }
00418 L999:
00419     smlnum = dlamch_("SAFEMIN");
00420     bignum = 1. / smlnum;
00421     smin = bignum;
00422     smax = 0.;
00423     t = 1. / sqrt(avg);
00424     base = dlamch_("B");
00425     u = 1. / log(base);
00426     i__1 = *n;
00427     for (i__ = 1; i__ <= i__1; ++i__) {
00428         i__2 = (integer) (u * log(s[i__] * t));
00429         s[i__] = pow_di(&base, &i__2);
00430 /* Computing MIN */
00431         d__1 = smin, d__2 = s[i__];
00432         smin = min(d__1,d__2);
00433 /* Computing MAX */
00434         d__1 = smax, d__2 = s[i__];
00435         smax = max(d__1,d__2);
00436     }
00437     *scond = max(smin,smlnum) / min(smax,bignum);
00438     return 0;
00439 } /* zheequb_ */


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