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


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