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


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