zhetf2.c
Go to the documentation of this file.
00001 /* zhetf2.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 zhetf2_(char *uplo, integer *n, doublecomplex *a, 
00021         integer *lda, integer *ipiv, integer *info)
00022 {
00023     /* System generated locals */
00024     integer a_dim1, a_offset, i__1, i__2, i__3, i__4, i__5, i__6;
00025     doublereal d__1, d__2, d__3, d__4;
00026     doublecomplex z__1, z__2, z__3, z__4, z__5, z__6;
00027 
00028     /* Builtin functions */
00029     double sqrt(doublereal), d_imag(doublecomplex *);
00030     void d_cnjg(doublecomplex *, doublecomplex *);
00031 
00032     /* Local variables */
00033     doublereal d__;
00034     integer i__, j, k;
00035     doublecomplex t;
00036     doublereal r1, d11;
00037     doublecomplex d12;
00038     doublereal d22;
00039     doublecomplex d21;
00040     integer kk, kp;
00041     doublecomplex wk;
00042     doublereal tt;
00043     doublecomplex wkm1, wkp1;
00044     integer imax, jmax;
00045     extern /* Subroutine */ int zher_(char *, integer *, doublereal *, 
00046             doublecomplex *, integer *, doublecomplex *, integer *);
00047     doublereal alpha;
00048     extern logical lsame_(char *, char *);
00049     integer kstep;
00050     logical upper;
00051     extern /* Subroutine */ int zswap_(integer *, doublecomplex *, integer *, 
00052             doublecomplex *, integer *);
00053     extern doublereal dlapy2_(doublereal *, doublereal *);
00054     doublereal absakk;
00055     extern logical disnan_(doublereal *);
00056     extern /* Subroutine */ int xerbla_(char *, integer *), zdscal_(
00057             integer *, doublereal *, doublecomplex *, integer *);
00058     doublereal colmax;
00059     extern integer izamax_(integer *, doublecomplex *, integer *);
00060     doublereal rowmax;
00061 
00062 
00063 /*  -- LAPACK routine (version 3.2) -- */
00064 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00065 /*     November 2006 */
00066 
00067 /*     .. Scalar Arguments .. */
00068 /*     .. */
00069 /*     .. Array Arguments .. */
00070 /*     .. */
00071 
00072 /*  Purpose */
00073 /*  ======= */
00074 
00075 /*  ZHETF2 computes the factorization of a complex Hermitian matrix A */
00076 /*  using the Bunch-Kaufman diagonal pivoting method: */
00077 
00078 /*     A = U*D*U'  or  A = L*D*L' */
00079 
00080 /*  where U (or L) is a product of permutation and unit upper (lower) */
00081 /*  triangular matrices, U' is the conjugate transpose of U, and D is */
00082 /*  Hermitian and block diagonal with 1-by-1 and 2-by-2 diagonal blocks. */
00083 
00084 /*  This is the unblocked version of the algorithm, calling Level 2 BLAS. */
00085 
00086 /*  Arguments */
00087 /*  ========= */
00088 
00089 /*  UPLO    (input) CHARACTER*1 */
00090 /*          Specifies whether the upper or lower triangular part of the */
00091 /*          Hermitian matrix A is stored: */
00092 /*          = 'U':  Upper triangular */
00093 /*          = 'L':  Lower triangular */
00094 
00095 /*  N       (input) INTEGER */
00096 /*          The order of the matrix A.  N >= 0. */
00097 
00098 /*  A       (input/output) COMPLEX*16 array, dimension (LDA,N) */
00099 /*          On entry, the Hermitian matrix A.  If UPLO = 'U', the leading */
00100 /*          n-by-n upper triangular part of A contains the upper */
00101 /*          triangular part of the matrix A, and the strictly lower */
00102 /*          triangular part of A is not referenced.  If UPLO = 'L', the */
00103 /*          leading n-by-n lower triangular part of A contains the lower */
00104 /*          triangular part of the matrix A, and the strictly upper */
00105 /*          triangular part of A is not referenced. */
00106 
00107 /*          On exit, the block diagonal matrix D and the multipliers used */
00108 /*          to obtain the factor U or L (see below for further details). */
00109 
00110 /*  LDA     (input) INTEGER */
00111 /*          The leading dimension of the array A.  LDA >= max(1,N). */
00112 
00113 /*  IPIV    (output) INTEGER array, dimension (N) */
00114 /*          Details of the interchanges and the block structure of D. */
00115 /*          If IPIV(k) > 0, then rows and columns k and IPIV(k) were */
00116 /*          interchanged and D(k,k) is a 1-by-1 diagonal block. */
00117 /*          If UPLO = 'U' and IPIV(k) = IPIV(k-1) < 0, then rows and */
00118 /*          columns k-1 and -IPIV(k) were interchanged and D(k-1:k,k-1:k) */
00119 /*          is a 2-by-2 diagonal block.  If UPLO = 'L' and IPIV(k) = */
00120 /*          IPIV(k+1) < 0, then rows and columns k+1 and -IPIV(k) were */
00121 /*          interchanged and D(k:k+1,k:k+1) is a 2-by-2 diagonal block. */
00122 
00123 /*  INFO    (output) INTEGER */
00124 /*          = 0: successful exit */
00125 /*          < 0: if INFO = -k, the k-th argument had an illegal value */
00126 /*          > 0: if INFO = k, D(k,k) is exactly zero.  The factorization */
00127 /*               has been completed, but the block diagonal matrix D is */
00128 /*               exactly singular, and division by zero will occur if it */
00129 /*               is used to solve a system of equations. */
00130 
00131 /*  Further Details */
00132 /*  =============== */
00133 
00134 /*  09-29-06 - patch from */
00135 /*    Bobby Cheng, MathWorks */
00136 
00137 /*    Replace l.210 and l.393 */
00138 /*         IF( MAX( ABSAKK, COLMAX ).EQ.ZERO ) THEN */
00139 /*    by */
00140 /*         IF( (MAX( ABSAKK, COLMAX ).EQ.ZERO) .OR. DISNAN(ABSAKK) ) THEN */
00141 
00142 /*  01-01-96 - Based on modifications by */
00143 /*    J. Lewis, Boeing Computer Services Company */
00144 /*    A. Petitet, Computer Science Dept., Univ. of Tenn., Knoxville, USA */
00145 
00146 /*  If UPLO = 'U', then A = U*D*U', where */
00147 /*     U = P(n)*U(n)* ... *P(k)U(k)* ..., */
00148 /*  i.e., U is a product of terms P(k)*U(k), where k decreases from n to */
00149 /*  1 in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1 */
00150 /*  and 2-by-2 diagonal blocks D(k).  P(k) is a permutation matrix as */
00151 /*  defined by IPIV(k), and U(k) is a unit upper triangular matrix, such */
00152 /*  that if the diagonal block D(k) is of order s (s = 1 or 2), then */
00153 
00154 /*             (   I    v    0   )   k-s */
00155 /*     U(k) =  (   0    I    0   )   s */
00156 /*             (   0    0    I   )   n-k */
00157 /*                k-s   s   n-k */
00158 
00159 /*  If s = 1, D(k) overwrites A(k,k), and v overwrites A(1:k-1,k). */
00160 /*  If s = 2, the upper triangle of D(k) overwrites A(k-1,k-1), A(k-1,k), */
00161 /*  and A(k,k), and v overwrites A(1:k-2,k-1:k). */
00162 
00163 /*  If UPLO = 'L', then A = L*D*L', where */
00164 /*     L = P(1)*L(1)* ... *P(k)*L(k)* ..., */
00165 /*  i.e., L is a product of terms P(k)*L(k), where k increases from 1 to */
00166 /*  n in steps of 1 or 2, and D is a block diagonal matrix with 1-by-1 */
00167 /*  and 2-by-2 diagonal blocks D(k).  P(k) is a permutation matrix as */
00168 /*  defined by IPIV(k), and L(k) is a unit lower triangular matrix, such */
00169 /*  that if the diagonal block D(k) is of order s (s = 1 or 2), then */
00170 
00171 /*             (   I    0     0   )  k-1 */
00172 /*     L(k) =  (   0    I     0   )  s */
00173 /*             (   0    v     I   )  n-k-s+1 */
00174 /*                k-1   s  n-k-s+1 */
00175 
00176 /*  If s = 1, D(k) overwrites A(k,k), and v overwrites A(k+1:n,k). */
00177 /*  If s = 2, the lower triangle of D(k) overwrites A(k,k), A(k+1,k), */
00178 /*  and A(k+1,k+1), and v overwrites A(k+2:n,k:k+1). */
00179 
00180 /*  ===================================================================== */
00181 
00182 /*     .. Parameters .. */
00183 /*     .. */
00184 /*     .. Local Scalars .. */
00185 /*     .. */
00186 /*     .. External Functions .. */
00187 /*     .. */
00188 /*     .. External Subroutines .. */
00189 /*     .. */
00190 /*     .. Intrinsic Functions .. */
00191 /*     .. */
00192 /*     .. Statement Functions .. */
00193 /*     .. */
00194 /*     .. Statement Function definitions .. */
00195 /*     .. */
00196 /*     .. Executable Statements .. */
00197 
00198 /*     Test the input parameters. */
00199 
00200     /* Parameter adjustments */
00201     a_dim1 = *lda;
00202     a_offset = 1 + a_dim1;
00203     a -= a_offset;
00204     --ipiv;
00205 
00206     /* Function Body */
00207     *info = 0;
00208     upper = lsame_(uplo, "U");
00209     if (! upper && ! lsame_(uplo, "L")) {
00210         *info = -1;
00211     } else if (*n < 0) {
00212         *info = -2;
00213     } else if (*lda < max(1,*n)) {
00214         *info = -4;
00215     }
00216     if (*info != 0) {
00217         i__1 = -(*info);
00218         xerbla_("ZHETF2", &i__1);
00219         return 0;
00220     }
00221 
00222 /*     Initialize ALPHA for use in choosing pivot block size. */
00223 
00224     alpha = (sqrt(17.) + 1.) / 8.;
00225 
00226     if (upper) {
00227 
00228 /*        Factorize A as U*D*U' using the upper triangle of A */
00229 
00230 /*        K is the main loop index, decreasing from N to 1 in steps of */
00231 /*        1 or 2 */
00232 
00233         k = *n;
00234 L10:
00235 
00236 /*        If K < 1, exit from loop */
00237 
00238         if (k < 1) {
00239             goto L90;
00240         }
00241         kstep = 1;
00242 
00243 /*        Determine rows and columns to be interchanged and whether */
00244 /*        a 1-by-1 or 2-by-2 pivot block will be used */
00245 
00246         i__1 = k + k * a_dim1;
00247         absakk = (d__1 = a[i__1].r, abs(d__1));
00248 
00249 /*        IMAX is the row-index of the largest off-diagonal element in */
00250 /*        column K, and COLMAX is its absolute value */
00251 
00252         if (k > 1) {
00253             i__1 = k - 1;
00254             imax = izamax_(&i__1, &a[k * a_dim1 + 1], &c__1);
00255             i__1 = imax + k * a_dim1;
00256             colmax = (d__1 = a[i__1].r, abs(d__1)) + (d__2 = d_imag(&a[imax + 
00257                     k * a_dim1]), abs(d__2));
00258         } else {
00259             colmax = 0.;
00260         }
00261 
00262         if (max(absakk,colmax) == 0. || disnan_(&absakk)) {
00263 
00264 /*           Column K is zero or contains a NaN: set INFO and continue */
00265 
00266             if (*info == 0) {
00267                 *info = k;
00268             }
00269             kp = k;
00270             i__1 = k + k * a_dim1;
00271             i__2 = k + k * a_dim1;
00272             d__1 = a[i__2].r;
00273             a[i__1].r = d__1, a[i__1].i = 0.;
00274         } else {
00275             if (absakk >= alpha * colmax) {
00276 
00277 /*              no interchange, use 1-by-1 pivot block */
00278 
00279                 kp = k;
00280             } else {
00281 
00282 /*              JMAX is the column-index of the largest off-diagonal */
00283 /*              element in row IMAX, and ROWMAX is its absolute value */
00284 
00285                 i__1 = k - imax;
00286                 jmax = imax + izamax_(&i__1, &a[imax + (imax + 1) * a_dim1], 
00287                         lda);
00288                 i__1 = imax + jmax * a_dim1;
00289                 rowmax = (d__1 = a[i__1].r, abs(d__1)) + (d__2 = d_imag(&a[
00290                         imax + jmax * a_dim1]), abs(d__2));
00291                 if (imax > 1) {
00292                     i__1 = imax - 1;
00293                     jmax = izamax_(&i__1, &a[imax * a_dim1 + 1], &c__1);
00294 /* Computing MAX */
00295                     i__1 = jmax + imax * a_dim1;
00296                     d__3 = rowmax, d__4 = (d__1 = a[i__1].r, abs(d__1)) + (
00297                             d__2 = d_imag(&a[jmax + imax * a_dim1]), abs(d__2)
00298                             );
00299                     rowmax = max(d__3,d__4);
00300                 }
00301 
00302                 if (absakk >= alpha * colmax * (colmax / rowmax)) {
00303 
00304 /*                 no interchange, use 1-by-1 pivot block */
00305 
00306                     kp = k;
00307                 } else /* if(complicated condition) */ {
00308                     i__1 = imax + imax * a_dim1;
00309                     if ((d__1 = a[i__1].r, abs(d__1)) >= alpha * rowmax) {
00310 
00311 /*                 interchange rows and columns K and IMAX, use 1-by-1 */
00312 /*                 pivot block */
00313 
00314                         kp = imax;
00315                     } else {
00316 
00317 /*                 interchange rows and columns K-1 and IMAX, use 2-by-2 */
00318 /*                 pivot block */
00319 
00320                         kp = imax;
00321                         kstep = 2;
00322                     }
00323                 }
00324             }
00325 
00326             kk = k - kstep + 1;
00327             if (kp != kk) {
00328 
00329 /*              Interchange rows and columns KK and KP in the leading */
00330 /*              submatrix A(1:k,1:k) */
00331 
00332                 i__1 = kp - 1;
00333                 zswap_(&i__1, &a[kk * a_dim1 + 1], &c__1, &a[kp * a_dim1 + 1], 
00334                          &c__1);
00335                 i__1 = kk - 1;
00336                 for (j = kp + 1; j <= i__1; ++j) {
00337                     d_cnjg(&z__1, &a[j + kk * a_dim1]);
00338                     t.r = z__1.r, t.i = z__1.i;
00339                     i__2 = j + kk * a_dim1;
00340                     d_cnjg(&z__1, &a[kp + j * a_dim1]);
00341                     a[i__2].r = z__1.r, a[i__2].i = z__1.i;
00342                     i__2 = kp + j * a_dim1;
00343                     a[i__2].r = t.r, a[i__2].i = t.i;
00344 /* L20: */
00345                 }
00346                 i__1 = kp + kk * a_dim1;
00347                 d_cnjg(&z__1, &a[kp + kk * a_dim1]);
00348                 a[i__1].r = z__1.r, a[i__1].i = z__1.i;
00349                 i__1 = kk + kk * a_dim1;
00350                 r1 = a[i__1].r;
00351                 i__1 = kk + kk * a_dim1;
00352                 i__2 = kp + kp * a_dim1;
00353                 d__1 = a[i__2].r;
00354                 a[i__1].r = d__1, a[i__1].i = 0.;
00355                 i__1 = kp + kp * a_dim1;
00356                 a[i__1].r = r1, a[i__1].i = 0.;
00357                 if (kstep == 2) {
00358                     i__1 = k + k * a_dim1;
00359                     i__2 = k + k * a_dim1;
00360                     d__1 = a[i__2].r;
00361                     a[i__1].r = d__1, a[i__1].i = 0.;
00362                     i__1 = k - 1 + k * a_dim1;
00363                     t.r = a[i__1].r, t.i = a[i__1].i;
00364                     i__1 = k - 1 + k * a_dim1;
00365                     i__2 = kp + k * a_dim1;
00366                     a[i__1].r = a[i__2].r, a[i__1].i = a[i__2].i;
00367                     i__1 = kp + k * a_dim1;
00368                     a[i__1].r = t.r, a[i__1].i = t.i;
00369                 }
00370             } else {
00371                 i__1 = k + k * a_dim1;
00372                 i__2 = k + k * a_dim1;
00373                 d__1 = a[i__2].r;
00374                 a[i__1].r = d__1, a[i__1].i = 0.;
00375                 if (kstep == 2) {
00376                     i__1 = k - 1 + (k - 1) * a_dim1;
00377                     i__2 = k - 1 + (k - 1) * a_dim1;
00378                     d__1 = a[i__2].r;
00379                     a[i__1].r = d__1, a[i__1].i = 0.;
00380                 }
00381             }
00382 
00383 /*           Update the leading submatrix */
00384 
00385             if (kstep == 1) {
00386 
00387 /*              1-by-1 pivot block D(k): column k now holds */
00388 
00389 /*              W(k) = U(k)*D(k) */
00390 
00391 /*              where U(k) is the k-th column of U */
00392 
00393 /*              Perform a rank-1 update of A(1:k-1,1:k-1) as */
00394 
00395 /*              A := A - U(k)*D(k)*U(k)' = A - W(k)*1/D(k)*W(k)' */
00396 
00397                 i__1 = k + k * a_dim1;
00398                 r1 = 1. / a[i__1].r;
00399                 i__1 = k - 1;
00400                 d__1 = -r1;
00401                 zher_(uplo, &i__1, &d__1, &a[k * a_dim1 + 1], &c__1, &a[
00402                         a_offset], lda);
00403 
00404 /*              Store U(k) in column k */
00405 
00406                 i__1 = k - 1;
00407                 zdscal_(&i__1, &r1, &a[k * a_dim1 + 1], &c__1);
00408             } else {
00409 
00410 /*              2-by-2 pivot block D(k): columns k and k-1 now hold */
00411 
00412 /*              ( W(k-1) W(k) ) = ( U(k-1) U(k) )*D(k) */
00413 
00414 /*              where U(k) and U(k-1) are the k-th and (k-1)-th columns */
00415 /*              of U */
00416 
00417 /*              Perform a rank-2 update of A(1:k-2,1:k-2) as */
00418 
00419 /*              A := A - ( U(k-1) U(k) )*D(k)*( U(k-1) U(k) )' */
00420 /*                 = A - ( W(k-1) W(k) )*inv(D(k))*( W(k-1) W(k) )' */
00421 
00422                 if (k > 2) {
00423 
00424                     i__1 = k - 1 + k * a_dim1;
00425                     d__1 = a[i__1].r;
00426                     d__2 = d_imag(&a[k - 1 + k * a_dim1]);
00427                     d__ = dlapy2_(&d__1, &d__2);
00428                     i__1 = k - 1 + (k - 1) * a_dim1;
00429                     d22 = a[i__1].r / d__;
00430                     i__1 = k + k * a_dim1;
00431                     d11 = a[i__1].r / d__;
00432                     tt = 1. / (d11 * d22 - 1.);
00433                     i__1 = k - 1 + k * a_dim1;
00434                     z__1.r = a[i__1].r / d__, z__1.i = a[i__1].i / d__;
00435                     d12.r = z__1.r, d12.i = z__1.i;
00436                     d__ = tt / d__;
00437 
00438                     for (j = k - 2; j >= 1; --j) {
00439                         i__1 = j + (k - 1) * a_dim1;
00440                         z__3.r = d11 * a[i__1].r, z__3.i = d11 * a[i__1].i;
00441                         d_cnjg(&z__5, &d12);
00442                         i__2 = j + k * a_dim1;
00443                         z__4.r = z__5.r * a[i__2].r - z__5.i * a[i__2].i, 
00444                                 z__4.i = z__5.r * a[i__2].i + z__5.i * a[i__2]
00445                                 .r;
00446                         z__2.r = z__3.r - z__4.r, z__2.i = z__3.i - z__4.i;
00447                         z__1.r = d__ * z__2.r, z__1.i = d__ * z__2.i;
00448                         wkm1.r = z__1.r, wkm1.i = z__1.i;
00449                         i__1 = j + k * a_dim1;
00450                         z__3.r = d22 * a[i__1].r, z__3.i = d22 * a[i__1].i;
00451                         i__2 = j + (k - 1) * a_dim1;
00452                         z__4.r = d12.r * a[i__2].r - d12.i * a[i__2].i, 
00453                                 z__4.i = d12.r * a[i__2].i + d12.i * a[i__2]
00454                                 .r;
00455                         z__2.r = z__3.r - z__4.r, z__2.i = z__3.i - z__4.i;
00456                         z__1.r = d__ * z__2.r, z__1.i = d__ * z__2.i;
00457                         wk.r = z__1.r, wk.i = z__1.i;
00458                         for (i__ = j; i__ >= 1; --i__) {
00459                             i__1 = i__ + j * a_dim1;
00460                             i__2 = i__ + j * a_dim1;
00461                             i__3 = i__ + k * a_dim1;
00462                             d_cnjg(&z__4, &wk);
00463                             z__3.r = a[i__3].r * z__4.r - a[i__3].i * z__4.i, 
00464                                     z__3.i = a[i__3].r * z__4.i + a[i__3].i * 
00465                                     z__4.r;
00466                             z__2.r = a[i__2].r - z__3.r, z__2.i = a[i__2].i - 
00467                                     z__3.i;
00468                             i__4 = i__ + (k - 1) * a_dim1;
00469                             d_cnjg(&z__6, &wkm1);
00470                             z__5.r = a[i__4].r * z__6.r - a[i__4].i * z__6.i, 
00471                                     z__5.i = a[i__4].r * z__6.i + a[i__4].i * 
00472                                     z__6.r;
00473                             z__1.r = z__2.r - z__5.r, z__1.i = z__2.i - 
00474                                     z__5.i;
00475                             a[i__1].r = z__1.r, a[i__1].i = z__1.i;
00476 /* L30: */
00477                         }
00478                         i__1 = j + k * a_dim1;
00479                         a[i__1].r = wk.r, a[i__1].i = wk.i;
00480                         i__1 = j + (k - 1) * a_dim1;
00481                         a[i__1].r = wkm1.r, a[i__1].i = wkm1.i;
00482                         i__1 = j + j * a_dim1;
00483                         i__2 = j + j * a_dim1;
00484                         d__1 = a[i__2].r;
00485                         z__1.r = d__1, z__1.i = 0.;
00486                         a[i__1].r = z__1.r, a[i__1].i = z__1.i;
00487 /* L40: */
00488                     }
00489 
00490                 }
00491 
00492             }
00493         }
00494 
00495 /*        Store details of the interchanges in IPIV */
00496 
00497         if (kstep == 1) {
00498             ipiv[k] = kp;
00499         } else {
00500             ipiv[k] = -kp;
00501             ipiv[k - 1] = -kp;
00502         }
00503 
00504 /*        Decrease K and return to the start of the main loop */
00505 
00506         k -= kstep;
00507         goto L10;
00508 
00509     } else {
00510 
00511 /*        Factorize A as L*D*L' using the lower triangle of A */
00512 
00513 /*        K is the main loop index, increasing from 1 to N in steps of */
00514 /*        1 or 2 */
00515 
00516         k = 1;
00517 L50:
00518 
00519 /*        If K > N, exit from loop */
00520 
00521         if (k > *n) {
00522             goto L90;
00523         }
00524         kstep = 1;
00525 
00526 /*        Determine rows and columns to be interchanged and whether */
00527 /*        a 1-by-1 or 2-by-2 pivot block will be used */
00528 
00529         i__1 = k + k * a_dim1;
00530         absakk = (d__1 = a[i__1].r, abs(d__1));
00531 
00532 /*        IMAX is the row-index of the largest off-diagonal element in */
00533 /*        column K, and COLMAX is its absolute value */
00534 
00535         if (k < *n) {
00536             i__1 = *n - k;
00537             imax = k + izamax_(&i__1, &a[k + 1 + k * a_dim1], &c__1);
00538             i__1 = imax + k * a_dim1;
00539             colmax = (d__1 = a[i__1].r, abs(d__1)) + (d__2 = d_imag(&a[imax + 
00540                     k * a_dim1]), abs(d__2));
00541         } else {
00542             colmax = 0.;
00543         }
00544 
00545         if (max(absakk,colmax) == 0. || disnan_(&absakk)) {
00546 
00547 /*           Column K is zero or contains a NaN: set INFO and continue */
00548 
00549             if (*info == 0) {
00550                 *info = k;
00551             }
00552             kp = k;
00553             i__1 = k + k * a_dim1;
00554             i__2 = k + k * a_dim1;
00555             d__1 = a[i__2].r;
00556             a[i__1].r = d__1, a[i__1].i = 0.;
00557         } else {
00558             if (absakk >= alpha * colmax) {
00559 
00560 /*              no interchange, use 1-by-1 pivot block */
00561 
00562                 kp = k;
00563             } else {
00564 
00565 /*              JMAX is the column-index of the largest off-diagonal */
00566 /*              element in row IMAX, and ROWMAX is its absolute value */
00567 
00568                 i__1 = imax - k;
00569                 jmax = k - 1 + izamax_(&i__1, &a[imax + k * a_dim1], lda);
00570                 i__1 = imax + jmax * a_dim1;
00571                 rowmax = (d__1 = a[i__1].r, abs(d__1)) + (d__2 = d_imag(&a[
00572                         imax + jmax * a_dim1]), abs(d__2));
00573                 if (imax < *n) {
00574                     i__1 = *n - imax;
00575                     jmax = imax + izamax_(&i__1, &a[imax + 1 + imax * a_dim1], 
00576                              &c__1);
00577 /* Computing MAX */
00578                     i__1 = jmax + imax * a_dim1;
00579                     d__3 = rowmax, d__4 = (d__1 = a[i__1].r, abs(d__1)) + (
00580                             d__2 = d_imag(&a[jmax + imax * a_dim1]), abs(d__2)
00581                             );
00582                     rowmax = max(d__3,d__4);
00583                 }
00584 
00585                 if (absakk >= alpha * colmax * (colmax / rowmax)) {
00586 
00587 /*                 no interchange, use 1-by-1 pivot block */
00588 
00589                     kp = k;
00590                 } else /* if(complicated condition) */ {
00591                     i__1 = imax + imax * a_dim1;
00592                     if ((d__1 = a[i__1].r, abs(d__1)) >= alpha * rowmax) {
00593 
00594 /*                 interchange rows and columns K and IMAX, use 1-by-1 */
00595 /*                 pivot block */
00596 
00597                         kp = imax;
00598                     } else {
00599 
00600 /*                 interchange rows and columns K+1 and IMAX, use 2-by-2 */
00601 /*                 pivot block */
00602 
00603                         kp = imax;
00604                         kstep = 2;
00605                     }
00606                 }
00607             }
00608 
00609             kk = k + kstep - 1;
00610             if (kp != kk) {
00611 
00612 /*              Interchange rows and columns KK and KP in the trailing */
00613 /*              submatrix A(k:n,k:n) */
00614 
00615                 if (kp < *n) {
00616                     i__1 = *n - kp;
00617                     zswap_(&i__1, &a[kp + 1 + kk * a_dim1], &c__1, &a[kp + 1 
00618                             + kp * a_dim1], &c__1);
00619                 }
00620                 i__1 = kp - 1;
00621                 for (j = kk + 1; j <= i__1; ++j) {
00622                     d_cnjg(&z__1, &a[j + kk * a_dim1]);
00623                     t.r = z__1.r, t.i = z__1.i;
00624                     i__2 = j + kk * a_dim1;
00625                     d_cnjg(&z__1, &a[kp + j * a_dim1]);
00626                     a[i__2].r = z__1.r, a[i__2].i = z__1.i;
00627                     i__2 = kp + j * a_dim1;
00628                     a[i__2].r = t.r, a[i__2].i = t.i;
00629 /* L60: */
00630                 }
00631                 i__1 = kp + kk * a_dim1;
00632                 d_cnjg(&z__1, &a[kp + kk * a_dim1]);
00633                 a[i__1].r = z__1.r, a[i__1].i = z__1.i;
00634                 i__1 = kk + kk * a_dim1;
00635                 r1 = a[i__1].r;
00636                 i__1 = kk + kk * a_dim1;
00637                 i__2 = kp + kp * a_dim1;
00638                 d__1 = a[i__2].r;
00639                 a[i__1].r = d__1, a[i__1].i = 0.;
00640                 i__1 = kp + kp * a_dim1;
00641                 a[i__1].r = r1, a[i__1].i = 0.;
00642                 if (kstep == 2) {
00643                     i__1 = k + k * a_dim1;
00644                     i__2 = k + k * a_dim1;
00645                     d__1 = a[i__2].r;
00646                     a[i__1].r = d__1, a[i__1].i = 0.;
00647                     i__1 = k + 1 + k * a_dim1;
00648                     t.r = a[i__1].r, t.i = a[i__1].i;
00649                     i__1 = k + 1 + k * a_dim1;
00650                     i__2 = kp + k * a_dim1;
00651                     a[i__1].r = a[i__2].r, a[i__1].i = a[i__2].i;
00652                     i__1 = kp + k * a_dim1;
00653                     a[i__1].r = t.r, a[i__1].i = t.i;
00654                 }
00655             } else {
00656                 i__1 = k + k * a_dim1;
00657                 i__2 = k + k * a_dim1;
00658                 d__1 = a[i__2].r;
00659                 a[i__1].r = d__1, a[i__1].i = 0.;
00660                 if (kstep == 2) {
00661                     i__1 = k + 1 + (k + 1) * a_dim1;
00662                     i__2 = k + 1 + (k + 1) * a_dim1;
00663                     d__1 = a[i__2].r;
00664                     a[i__1].r = d__1, a[i__1].i = 0.;
00665                 }
00666             }
00667 
00668 /*           Update the trailing submatrix */
00669 
00670             if (kstep == 1) {
00671 
00672 /*              1-by-1 pivot block D(k): column k now holds */
00673 
00674 /*              W(k) = L(k)*D(k) */
00675 
00676 /*              where L(k) is the k-th column of L */
00677 
00678                 if (k < *n) {
00679 
00680 /*                 Perform a rank-1 update of A(k+1:n,k+1:n) as */
00681 
00682 /*                 A := A - L(k)*D(k)*L(k)' = A - W(k)*(1/D(k))*W(k)' */
00683 
00684                     i__1 = k + k * a_dim1;
00685                     r1 = 1. / a[i__1].r;
00686                     i__1 = *n - k;
00687                     d__1 = -r1;
00688                     zher_(uplo, &i__1, &d__1, &a[k + 1 + k * a_dim1], &c__1, &
00689                             a[k + 1 + (k + 1) * a_dim1], lda);
00690 
00691 /*                 Store L(k) in column K */
00692 
00693                     i__1 = *n - k;
00694                     zdscal_(&i__1, &r1, &a[k + 1 + k * a_dim1], &c__1);
00695                 }
00696             } else {
00697 
00698 /*              2-by-2 pivot block D(k) */
00699 
00700                 if (k < *n - 1) {
00701 
00702 /*                 Perform a rank-2 update of A(k+2:n,k+2:n) as */
00703 
00704 /*                 A := A - ( L(k) L(k+1) )*D(k)*( L(k) L(k+1) )' */
00705 /*                    = A - ( W(k) W(k+1) )*inv(D(k))*( W(k) W(k+1) )' */
00706 
00707 /*                 where L(k) and L(k+1) are the k-th and (k+1)-th */
00708 /*                 columns of L */
00709 
00710                     i__1 = k + 1 + k * a_dim1;
00711                     d__1 = a[i__1].r;
00712                     d__2 = d_imag(&a[k + 1 + k * a_dim1]);
00713                     d__ = dlapy2_(&d__1, &d__2);
00714                     i__1 = k + 1 + (k + 1) * a_dim1;
00715                     d11 = a[i__1].r / d__;
00716                     i__1 = k + k * a_dim1;
00717                     d22 = a[i__1].r / d__;
00718                     tt = 1. / (d11 * d22 - 1.);
00719                     i__1 = k + 1 + k * a_dim1;
00720                     z__1.r = a[i__1].r / d__, z__1.i = a[i__1].i / d__;
00721                     d21.r = z__1.r, d21.i = z__1.i;
00722                     d__ = tt / d__;
00723 
00724                     i__1 = *n;
00725                     for (j = k + 2; j <= i__1; ++j) {
00726                         i__2 = j + k * a_dim1;
00727                         z__3.r = d11 * a[i__2].r, z__3.i = d11 * a[i__2].i;
00728                         i__3 = j + (k + 1) * a_dim1;
00729                         z__4.r = d21.r * a[i__3].r - d21.i * a[i__3].i, 
00730                                 z__4.i = d21.r * a[i__3].i + d21.i * a[i__3]
00731                                 .r;
00732                         z__2.r = z__3.r - z__4.r, z__2.i = z__3.i - z__4.i;
00733                         z__1.r = d__ * z__2.r, z__1.i = d__ * z__2.i;
00734                         wk.r = z__1.r, wk.i = z__1.i;
00735                         i__2 = j + (k + 1) * a_dim1;
00736                         z__3.r = d22 * a[i__2].r, z__3.i = d22 * a[i__2].i;
00737                         d_cnjg(&z__5, &d21);
00738                         i__3 = j + k * a_dim1;
00739                         z__4.r = z__5.r * a[i__3].r - z__5.i * a[i__3].i, 
00740                                 z__4.i = z__5.r * a[i__3].i + z__5.i * a[i__3]
00741                                 .r;
00742                         z__2.r = z__3.r - z__4.r, z__2.i = z__3.i - z__4.i;
00743                         z__1.r = d__ * z__2.r, z__1.i = d__ * z__2.i;
00744                         wkp1.r = z__1.r, wkp1.i = z__1.i;
00745                         i__2 = *n;
00746                         for (i__ = j; i__ <= i__2; ++i__) {
00747                             i__3 = i__ + j * a_dim1;
00748                             i__4 = i__ + j * a_dim1;
00749                             i__5 = i__ + k * a_dim1;
00750                             d_cnjg(&z__4, &wk);
00751                             z__3.r = a[i__5].r * z__4.r - a[i__5].i * z__4.i, 
00752                                     z__3.i = a[i__5].r * z__4.i + a[i__5].i * 
00753                                     z__4.r;
00754                             z__2.r = a[i__4].r - z__3.r, z__2.i = a[i__4].i - 
00755                                     z__3.i;
00756                             i__6 = i__ + (k + 1) * a_dim1;
00757                             d_cnjg(&z__6, &wkp1);
00758                             z__5.r = a[i__6].r * z__6.r - a[i__6].i * z__6.i, 
00759                                     z__5.i = a[i__6].r * z__6.i + a[i__6].i * 
00760                                     z__6.r;
00761                             z__1.r = z__2.r - z__5.r, z__1.i = z__2.i - 
00762                                     z__5.i;
00763                             a[i__3].r = z__1.r, a[i__3].i = z__1.i;
00764 /* L70: */
00765                         }
00766                         i__2 = j + k * a_dim1;
00767                         a[i__2].r = wk.r, a[i__2].i = wk.i;
00768                         i__2 = j + (k + 1) * a_dim1;
00769                         a[i__2].r = wkp1.r, a[i__2].i = wkp1.i;
00770                         i__2 = j + j * a_dim1;
00771                         i__3 = j + j * a_dim1;
00772                         d__1 = a[i__3].r;
00773                         z__1.r = d__1, z__1.i = 0.;
00774                         a[i__2].r = z__1.r, a[i__2].i = z__1.i;
00775 /* L80: */
00776                     }
00777                 }
00778             }
00779         }
00780 
00781 /*        Store details of the interchanges in IPIV */
00782 
00783         if (kstep == 1) {
00784             ipiv[k] = kp;
00785         } else {
00786             ipiv[k] = -kp;
00787             ipiv[k + 1] = -kp;
00788         }
00789 
00790 /*        Increase K and return to the start of the main loop */
00791 
00792         k += kstep;
00793         goto L50;
00794 
00795     }
00796 
00797 L90:
00798     return 0;
00799 
00800 /*     End of ZHETF2 */
00801 
00802 } /* zhetf2_ */


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