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


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