spstf2.c
Go to the documentation of this file.
00001 /* spstf2.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 real c_b16 = -1.f;
00020 static real c_b18 = 1.f;
00021 
00022 /* Subroutine */ int spstf2_(char *uplo, integer *n, real *a, integer *lda, 
00023         integer *piv, integer *rank, real *tol, real *work, integer *info)
00024 {
00025     /* System generated locals */
00026     integer a_dim1, a_offset, i__1, i__2, i__3;
00027     real r__1;
00028 
00029     /* Builtin functions */
00030     double sqrt(doublereal);
00031 
00032     /* Local variables */
00033     integer i__, j, maxlocval;
00034     real ajj;
00035     integer pvt;
00036     extern logical lsame_(char *, char *);
00037     extern /* Subroutine */ int sscal_(integer *, real *, real *, integer *);
00038     integer itemp;
00039     extern /* Subroutine */ int sgemv_(char *, integer *, integer *, real *, 
00040             real *, integer *, real *, integer *, real *, real *, integer *);
00041     real stemp;
00042     logical upper;
00043     extern /* Subroutine */ int sswap_(integer *, real *, integer *, real *, 
00044             integer *);
00045     real sstop;
00046     extern doublereal slamch_(char *);
00047     extern /* Subroutine */ int xerbla_(char *, integer *);
00048     extern logical sisnan_(real *);
00049     extern integer smaxloc_(real *, integer *);
00050 
00051 
00052 /*  -- LAPACK PROTOTYPE routine (version 3.2) -- */
00053 /*     Craig Lucas, University of Manchester / NAG Ltd. */
00054 /*     October, 2008 */
00055 
00056 /*     .. Scalar Arguments .. */
00057 /*     .. */
00058 /*     .. Array Arguments .. */
00059 /*     .. */
00060 
00061 /*  Purpose */
00062 /*  ======= */
00063 
00064 /*  SPSTF2 computes the Cholesky factorization with complete */
00065 /*  pivoting of a real symmetric positive semidefinite matrix A. */
00066 
00067 /*  The factorization has the form */
00068 /*     P' * A * P = U' * U ,  if UPLO = 'U', */
00069 /*     P' * A * P = L  * L',  if UPLO = 'L', */
00070 /*  where U is an upper triangular matrix and L is lower triangular, and */
00071 /*  P is stored as vector PIV. */
00072 
00073 /*  This algorithm does not attempt to check that A is positive */
00074 /*  semidefinite. This version of the algorithm calls level 2 BLAS. */
00075 
00076 /*  Arguments */
00077 /*  ========= */
00078 
00079 /*  UPLO    (input) CHARACTER*1 */
00080 /*          Specifies whether the upper or lower triangular part of the */
00081 /*          symmetric matrix A is stored. */
00082 /*          = 'U':  Upper triangular */
00083 /*          = 'L':  Lower triangular */
00084 
00085 /*  N       (input) INTEGER */
00086 /*          The order of the matrix A.  N >= 0. */
00087 
00088 /*  A       (input/output) REAL array, dimension (LDA,N) */
00089 /*          On entry, the symmetric matrix A.  If UPLO = 'U', the leading */
00090 /*          n by n upper triangular part of A contains the upper */
00091 /*          triangular part of the matrix A, and the strictly lower */
00092 /*          triangular part of A is not referenced.  If UPLO = 'L', the */
00093 /*          leading n by n lower triangular part of A contains the lower */
00094 /*          triangular part of the matrix A, and the strictly upper */
00095 /*          triangular part of A is not referenced. */
00096 
00097 /*          On exit, if INFO = 0, the factor U or L from the Cholesky */
00098 /*          factorization as above. */
00099 
00100 /*  PIV     (output) INTEGER array, dimension (N) */
00101 /*          PIV is such that the nonzero entries are P( PIV(K), K ) = 1. */
00102 
00103 /*  RANK    (output) INTEGER */
00104 /*          The rank of A given by the number of steps the algorithm */
00105 /*          completed. */
00106 
00107 /*  TOL     (input) REAL */
00108 /*          User defined tolerance. If TOL < 0, then N*U*MAX( A( K,K ) ) */
00109 /*          will be used. The algorithm terminates at the (K-1)st step */
00110 /*          if the pivot <= TOL. */
00111 
00112 /*  LDA     (input) INTEGER */
00113 /*          The leading dimension of the array A.  LDA >= max(1,N). */
00114 
00115 /*  WORK    REAL array, dimension (2*N) */
00116 /*          Work space. */
00117 
00118 /*  INFO    (output) INTEGER */
00119 /*          < 0: If INFO = -K, the K-th argument had an illegal value, */
00120 /*          = 0: algorithm completed successfully, and */
00121 /*          > 0: the matrix A is either rank deficient with computed rank */
00122 /*               as returned in RANK, or is indefinite.  See Section 7 of */
00123 /*               LAPACK Working Note #161 for further information. */
00124 
00125 /*  ===================================================================== */
00126 
00127 /*     .. Parameters .. */
00128 /*     .. */
00129 /*     .. Local Scalars .. */
00130 /*     .. */
00131 /*     .. External Functions .. */
00132 /*     .. */
00133 /*     .. External Subroutines .. */
00134 /*     .. */
00135 /*     .. Intrinsic Functions .. */
00136 /*     .. */
00137 /*     .. Executable Statements .. */
00138 
00139 /*     Test the input parameters */
00140 
00141     /* Parameter adjustments */
00142     --work;
00143     --piv;
00144     a_dim1 = *lda;
00145     a_offset = 1 + a_dim1;
00146     a -= a_offset;
00147 
00148     /* Function Body */
00149     *info = 0;
00150     upper = lsame_(uplo, "U");
00151     if (! upper && ! lsame_(uplo, "L")) {
00152         *info = -1;
00153     } else if (*n < 0) {
00154         *info = -2;
00155     } else if (*lda < max(1,*n)) {
00156         *info = -4;
00157     }
00158     if (*info != 0) {
00159         i__1 = -(*info);
00160         xerbla_("SPSTF2", &i__1);
00161         return 0;
00162     }
00163 
00164 /*     Quick return if possible */
00165 
00166     if (*n == 0) {
00167         return 0;
00168     }
00169 
00170 /*     Initialize PIV */
00171 
00172     i__1 = *n;
00173     for (i__ = 1; i__ <= i__1; ++i__) {
00174         piv[i__] = i__;
00175 /* L100: */
00176     }
00177 
00178 /*     Compute stopping value */
00179 
00180     pvt = 1;
00181     ajj = a[pvt + pvt * a_dim1];
00182     i__1 = *n;
00183     for (i__ = 2; i__ <= i__1; ++i__) {
00184         if (a[i__ + i__ * a_dim1] > ajj) {
00185             pvt = i__;
00186             ajj = a[pvt + pvt * a_dim1];
00187         }
00188     }
00189     if (ajj == 0.f || sisnan_(&ajj)) {
00190         *rank = 0;
00191         *info = 1;
00192         goto L170;
00193     }
00194 
00195 /*     Compute stopping value if not supplied */
00196 
00197     if (*tol < 0.f) {
00198         sstop = *n * slamch_("Epsilon") * ajj;
00199     } else {
00200         sstop = *tol;
00201     }
00202 
00203 /*     Set first half of WORK to zero, holds dot products */
00204 
00205     i__1 = *n;
00206     for (i__ = 1; i__ <= i__1; ++i__) {
00207         work[i__] = 0.f;
00208 /* L110: */
00209     }
00210 
00211     if (upper) {
00212 
00213 /*        Compute the Cholesky factorization P' * A * P = U' * U */
00214 
00215         i__1 = *n;
00216         for (j = 1; j <= i__1; ++j) {
00217 
00218 /*        Find pivot, test for exit, else swap rows and columns */
00219 /*        Update dot products, compute possible pivots which are */
00220 /*        stored in the second half of WORK */
00221 
00222             i__2 = *n;
00223             for (i__ = j; i__ <= i__2; ++i__) {
00224 
00225                 if (j > 1) {
00226 /* Computing 2nd power */
00227                     r__1 = a[j - 1 + i__ * a_dim1];
00228                     work[i__] += r__1 * r__1;
00229                 }
00230                 work[*n + i__] = a[i__ + i__ * a_dim1] - work[i__];
00231 
00232 /* L120: */
00233             }
00234 
00235             if (j > 1) {
00236                 maxlocval = (*n << 1) - (*n + j) + 1;
00237                 itemp = smaxloc_(&work[*n + j], &maxlocval);
00238                 pvt = itemp + j - 1;
00239                 ajj = work[*n + pvt];
00240                 if (ajj <= sstop || sisnan_(&ajj)) {
00241                     a[j + j * a_dim1] = ajj;
00242                     goto L160;
00243                 }
00244             }
00245 
00246             if (j != pvt) {
00247 
00248 /*              Pivot OK, so can now swap pivot rows and columns */
00249 
00250                 a[pvt + pvt * a_dim1] = a[j + j * a_dim1];
00251                 i__2 = j - 1;
00252                 sswap_(&i__2, &a[j * a_dim1 + 1], &c__1, &a[pvt * a_dim1 + 1], 
00253                          &c__1);
00254                 if (pvt < *n) {
00255                     i__2 = *n - pvt;
00256                     sswap_(&i__2, &a[j + (pvt + 1) * a_dim1], lda, &a[pvt + (
00257                             pvt + 1) * a_dim1], lda);
00258                 }
00259                 i__2 = pvt - j - 1;
00260                 sswap_(&i__2, &a[j + (j + 1) * a_dim1], lda, &a[j + 1 + pvt * 
00261                         a_dim1], &c__1);
00262 
00263 /*              Swap dot products and PIV */
00264 
00265                 stemp = work[j];
00266                 work[j] = work[pvt];
00267                 work[pvt] = stemp;
00268                 itemp = piv[pvt];
00269                 piv[pvt] = piv[j];
00270                 piv[j] = itemp;
00271             }
00272 
00273             ajj = sqrt(ajj);
00274             a[j + j * a_dim1] = ajj;
00275 
00276 /*           Compute elements J+1:N of row J */
00277 
00278             if (j < *n) {
00279                 i__2 = j - 1;
00280                 i__3 = *n - j;
00281                 sgemv_("Trans", &i__2, &i__3, &c_b16, &a[(j + 1) * a_dim1 + 1]
00282 , lda, &a[j * a_dim1 + 1], &c__1, &c_b18, &a[j + (j + 
00283                         1) * a_dim1], lda);
00284                 i__2 = *n - j;
00285                 r__1 = 1.f / ajj;
00286                 sscal_(&i__2, &r__1, &a[j + (j + 1) * a_dim1], lda);
00287             }
00288 
00289 /* L130: */
00290         }
00291 
00292     } else {
00293 
00294 /*        Compute the Cholesky factorization P' * A * P = L * L' */
00295 
00296         i__1 = *n;
00297         for (j = 1; j <= i__1; ++j) {
00298 
00299 /*        Find pivot, test for exit, else swap rows and columns */
00300 /*        Update dot products, compute possible pivots which are */
00301 /*        stored in the second half of WORK */
00302 
00303             i__2 = *n;
00304             for (i__ = j; i__ <= i__2; ++i__) {
00305 
00306                 if (j > 1) {
00307 /* Computing 2nd power */
00308                     r__1 = a[i__ + (j - 1) * a_dim1];
00309                     work[i__] += r__1 * r__1;
00310                 }
00311                 work[*n + i__] = a[i__ + i__ * a_dim1] - work[i__];
00312 
00313 /* L140: */
00314             }
00315 
00316             if (j > 1) {
00317                 maxlocval = (*n << 1) - (*n + j) + 1;
00318                 itemp = smaxloc_(&work[*n + j], &maxlocval);
00319                 pvt = itemp + j - 1;
00320                 ajj = work[*n + pvt];
00321                 if (ajj <= sstop || sisnan_(&ajj)) {
00322                     a[j + j * a_dim1] = ajj;
00323                     goto L160;
00324                 }
00325             }
00326 
00327             if (j != pvt) {
00328 
00329 /*              Pivot OK, so can now swap pivot rows and columns */
00330 
00331                 a[pvt + pvt * a_dim1] = a[j + j * a_dim1];
00332                 i__2 = j - 1;
00333                 sswap_(&i__2, &a[j + a_dim1], lda, &a[pvt + a_dim1], lda);
00334                 if (pvt < *n) {
00335                     i__2 = *n - pvt;
00336                     sswap_(&i__2, &a[pvt + 1 + j * a_dim1], &c__1, &a[pvt + 1 
00337                             + pvt * a_dim1], &c__1);
00338                 }
00339                 i__2 = pvt - j - 1;
00340                 sswap_(&i__2, &a[j + 1 + j * a_dim1], &c__1, &a[pvt + (j + 1) 
00341                         * a_dim1], lda);
00342 
00343 /*              Swap dot products and PIV */
00344 
00345                 stemp = work[j];
00346                 work[j] = work[pvt];
00347                 work[pvt] = stemp;
00348                 itemp = piv[pvt];
00349                 piv[pvt] = piv[j];
00350                 piv[j] = itemp;
00351             }
00352 
00353             ajj = sqrt(ajj);
00354             a[j + j * a_dim1] = ajj;
00355 
00356 /*           Compute elements J+1:N of column J */
00357 
00358             if (j < *n) {
00359                 i__2 = *n - j;
00360                 i__3 = j - 1;
00361                 sgemv_("No Trans", &i__2, &i__3, &c_b16, &a[j + 1 + a_dim1], 
00362                         lda, &a[j + a_dim1], lda, &c_b18, &a[j + 1 + j * 
00363                         a_dim1], &c__1);
00364                 i__2 = *n - j;
00365                 r__1 = 1.f / ajj;
00366                 sscal_(&i__2, &r__1, &a[j + 1 + j * a_dim1], &c__1);
00367             }
00368 
00369 /* L150: */
00370         }
00371 
00372     }
00373 
00374 /*     Ran to completion, A has full rank */
00375 
00376     *rank = *n;
00377 
00378     goto L170;
00379 L160:
00380 
00381 /*     Rank is number of steps completed.  Set INFO = 1 to signal */
00382 /*     that the factorization cannot be used to solve a system. */
00383 
00384     *rank = j - 1;
00385     *info = 1;
00386 
00387 L170:
00388     return 0;
00389 
00390 /*     End of SPSTF2 */
00391 
00392 } /* spstf2_ */


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