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


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