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


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