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


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:55:32