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


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