cpst01.c
Go to the documentation of this file.
00001 /* cpst01.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_b20 = 1.f;
00020 
00021 /* Subroutine */ int cpst01_(char *uplo, integer *n, complex *a, integer *lda, 
00022          complex *afac, integer *ldafac, complex *perm, integer *ldperm, 
00023         integer *piv, real *rwork, real *resid, integer *rank)
00024 {
00025     /* System generated locals */
00026     integer a_dim1, a_offset, afac_dim1, afac_offset, perm_dim1, perm_offset, 
00027             i__1, i__2, i__3, i__4, i__5;
00028     real r__1;
00029     complex q__1;
00030 
00031     /* Builtin functions */
00032     double r_imag(complex *);
00033     void r_cnjg(complex *, complex *);
00034 
00035     /* Local variables */
00036     integer i__, j, k;
00037     complex tc;
00038     real tr, eps;
00039     extern /* Subroutine */ int cher_(char *, integer *, real *, complex *, 
00040             integer *, complex *, integer *), cscal_(integer *, 
00041             complex *, complex *, integer *);
00042     extern /* Complex */ VOID cdotc_(complex *, integer *, complex *, integer 
00043             *, complex *, integer *);
00044     extern logical lsame_(char *, char *);
00045     real anorm;
00046     extern /* Subroutine */ int ctrmv_(char *, char *, char *, integer *, 
00047             complex *, integer *, complex *, integer *);
00048     extern doublereal clanhe_(char *, char *, integer *, complex *, integer *, 
00049              real *), slamch_(char *);
00050 
00051 
00052 /*  -- LAPACK test routine (version 3.1) -- */
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 /*  CPST01 reconstructs an Hermitian positive semidefinite matrix A */
00065 /*  from its L or U factors and the permutation matrix P and computes */
00066 /*  the residual */
00067 /*     norm( P*L*L'*P' - A ) / ( N * norm(A) * EPS ) or */
00068 /*     norm( P*U'*U*P' - A ) / ( N * norm(A) * EPS ), */
00069 /*  where EPS is the machine epsilon, L' is the conjugate transpose of L, */
00070 /*  and U' is the conjugate transpose of U. */
00071 
00072 /*  Arguments */
00073 /*  ========== */
00074 
00075 /*  UPLO    (input) CHARACTER*1 */
00076 /*          Specifies whether the upper or lower triangular part of the */
00077 /*          Hermitian matrix A is stored: */
00078 /*          = 'U':  Upper triangular */
00079 /*          = 'L':  Lower triangular */
00080 
00081 /*  N       (input) INTEGER */
00082 /*          The number of rows and columns of the matrix A.  N >= 0. */
00083 
00084 /*  A       (input) COMPLEX array, dimension (LDA,N) */
00085 /*          The original Hermitian matrix A. */
00086 
00087 /*  LDA     (input) INTEGER */
00088 /*          The leading dimension of the array A.  LDA >= max(1,N) */
00089 
00090 /*  AFAC    (input) COMPLEX array, dimension (LDAFAC,N) */
00091 /*          The factor L or U from the L*L' or U'*U */
00092 /*          factorization of A. */
00093 
00094 /*  LDAFAC  (input) INTEGER */
00095 /*          The leading dimension of the array AFAC.  LDAFAC >= max(1,N). */
00096 
00097 /*  PERM    (output) COMPLEX array, dimension (LDPERM,N) */
00098 /*          Overwritten with the reconstructed matrix, and then with the */
00099 /*          difference P*L*L'*P' - A (or P*U'*U*P' - A) */
00100 
00101 /*  LDPERM  (input) INTEGER */
00102 /*          The leading dimension of the array PERM. */
00103 /*          LDAPERM >= max(1,N). */
00104 
00105 /*  PIV     (input) INTEGER array, dimension (N) */
00106 /*          PIV is such that the nonzero entries are */
00107 /*          P( PIV( K ), K ) = 1. */
00108 
00109 /*  RWORK   (workspace) REAL array, dimension (N) */
00110 
00111 /*  RESID   (output) REAL */
00112 /*          If UPLO = 'L', norm(L*L' - A) / ( N * norm(A) * EPS ) */
00113 /*          If UPLO = 'U', norm(U'*U - A) / ( N * norm(A) * EPS ) */
00114 
00115 /*  ===================================================================== */
00116 
00117 /*     .. Parameters .. */
00118 /*     .. */
00119 /*     .. Local Scalars .. */
00120 /*     .. */
00121 /*     .. External Functions .. */
00122 /*     .. */
00123 /*     .. External Subroutines .. */
00124 /*     .. */
00125 /*     .. Intrinsic Functions .. */
00126 /*     .. */
00127 /*     .. Executable Statements .. */
00128 
00129 /*     Quick exit if N = 0. */
00130 
00131     /* Parameter adjustments */
00132     a_dim1 = *lda;
00133     a_offset = 1 + a_dim1;
00134     a -= a_offset;
00135     afac_dim1 = *ldafac;
00136     afac_offset = 1 + afac_dim1;
00137     afac -= afac_offset;
00138     perm_dim1 = *ldperm;
00139     perm_offset = 1 + perm_dim1;
00140     perm -= perm_offset;
00141     --piv;
00142     --rwork;
00143 
00144     /* Function Body */
00145     if (*n <= 0) {
00146         *resid = 0.f;
00147         return 0;
00148     }
00149 
00150 /*     Exit with RESID = 1/EPS if ANORM = 0. */
00151 
00152     eps = slamch_("Epsilon");
00153     anorm = clanhe_("1", uplo, n, &a[a_offset], lda, &rwork[1]);
00154     if (anorm <= 0.f) {
00155         *resid = 1.f / eps;
00156         return 0;
00157     }
00158 
00159 /*     Check the imaginary parts of the diagonal elements and return with */
00160 /*     an error code if any are nonzero. */
00161 
00162     i__1 = *n;
00163     for (j = 1; j <= i__1; ++j) {
00164         if (r_imag(&afac[j + j * afac_dim1]) != 0.f) {
00165             *resid = 1.f / eps;
00166             return 0;
00167         }
00168 /* L100: */
00169     }
00170 
00171 /*     Compute the product U'*U, overwriting U. */
00172 
00173     if (lsame_(uplo, "U")) {
00174 
00175         if (*rank < *n) {
00176             i__1 = *n;
00177             for (j = *rank + 1; j <= i__1; ++j) {
00178                 i__2 = j;
00179                 for (i__ = *rank + 1; i__ <= i__2; ++i__) {
00180                     i__3 = i__ + j * afac_dim1;
00181                     afac[i__3].r = 0.f, afac[i__3].i = 0.f;
00182 /* L110: */
00183                 }
00184 /* L120: */
00185             }
00186         }
00187 
00188         for (k = *n; k >= 1; --k) {
00189 
00190 /*           Compute the (K,K) element of the result. */
00191 
00192             cdotc_(&q__1, &k, &afac[k * afac_dim1 + 1], &c__1, &afac[k * 
00193                     afac_dim1 + 1], &c__1);
00194             tr = q__1.r;
00195             i__1 = k + k * afac_dim1;
00196             afac[i__1].r = tr, afac[i__1].i = 0.f;
00197 
00198 /*           Compute the rest of column K. */
00199 
00200             i__1 = k - 1;
00201             ctrmv_("Upper", "Conjugate", "Non-unit", &i__1, &afac[afac_offset]
00202 , ldafac, &afac[k * afac_dim1 + 1], &c__1);
00203 
00204 /* L130: */
00205         }
00206 
00207 /*     Compute the product L*L', overwriting L. */
00208 
00209     } else {
00210 
00211         if (*rank < *n) {
00212             i__1 = *n;
00213             for (j = *rank + 1; j <= i__1; ++j) {
00214                 i__2 = *n;
00215                 for (i__ = j; i__ <= i__2; ++i__) {
00216                     i__3 = i__ + j * afac_dim1;
00217                     afac[i__3].r = 0.f, afac[i__3].i = 0.f;
00218 /* L140: */
00219                 }
00220 /* L150: */
00221             }
00222         }
00223 
00224         for (k = *n; k >= 1; --k) {
00225 /*           Add a multiple of column K of the factor L to each of */
00226 /*           columns K+1 through N. */
00227 
00228             if (k + 1 <= *n) {
00229                 i__1 = *n - k;
00230                 cher_("Lower", &i__1, &c_b20, &afac[k + 1 + k * afac_dim1], &
00231                         c__1, &afac[k + 1 + (k + 1) * afac_dim1], ldafac);
00232             }
00233 
00234 /*           Scale column K by the diagonal element. */
00235 
00236             i__1 = k + k * afac_dim1;
00237             tc.r = afac[i__1].r, tc.i = afac[i__1].i;
00238             i__1 = *n - k + 1;
00239             cscal_(&i__1, &tc, &afac[k + k * afac_dim1], &c__1);
00240 /* L160: */
00241         }
00242 
00243     }
00244 
00245 /*        Form P*L*L'*P' or P*U'*U*P' */
00246 
00247     if (lsame_(uplo, "U")) {
00248 
00249         i__1 = *n;
00250         for (j = 1; j <= i__1; ++j) {
00251             i__2 = *n;
00252             for (i__ = 1; i__ <= i__2; ++i__) {
00253                 if (piv[i__] <= piv[j]) {
00254                     if (i__ <= j) {
00255                         i__3 = piv[i__] + piv[j] * perm_dim1;
00256                         i__4 = i__ + j * afac_dim1;
00257                         perm[i__3].r = afac[i__4].r, perm[i__3].i = afac[i__4]
00258                                 .i;
00259                     } else {
00260                         i__3 = piv[i__] + piv[j] * perm_dim1;
00261                         r_cnjg(&q__1, &afac[j + i__ * afac_dim1]);
00262                         perm[i__3].r = q__1.r, perm[i__3].i = q__1.i;
00263                     }
00264                 }
00265 /* L170: */
00266             }
00267 /* L180: */
00268         }
00269 
00270 
00271     } else {
00272 
00273         i__1 = *n;
00274         for (j = 1; j <= i__1; ++j) {
00275             i__2 = *n;
00276             for (i__ = 1; i__ <= i__2; ++i__) {
00277                 if (piv[i__] >= piv[j]) {
00278                     if (i__ >= j) {
00279                         i__3 = piv[i__] + piv[j] * perm_dim1;
00280                         i__4 = i__ + j * afac_dim1;
00281                         perm[i__3].r = afac[i__4].r, perm[i__3].i = afac[i__4]
00282                                 .i;
00283                     } else {
00284                         i__3 = piv[i__] + piv[j] * perm_dim1;
00285                         r_cnjg(&q__1, &afac[j + i__ * afac_dim1]);
00286                         perm[i__3].r = q__1.r, perm[i__3].i = q__1.i;
00287                     }
00288                 }
00289 /* L190: */
00290             }
00291 /* L200: */
00292         }
00293 
00294     }
00295 
00296 /*     Compute the difference  P*L*L'*P' - A (or P*U'*U*P' - A). */
00297 
00298     if (lsame_(uplo, "U")) {
00299         i__1 = *n;
00300         for (j = 1; j <= i__1; ++j) {
00301             i__2 = j - 1;
00302             for (i__ = 1; i__ <= i__2; ++i__) {
00303                 i__3 = i__ + j * perm_dim1;
00304                 i__4 = i__ + j * perm_dim1;
00305                 i__5 = i__ + j * a_dim1;
00306                 q__1.r = perm[i__4].r - a[i__5].r, q__1.i = perm[i__4].i - a[
00307                         i__5].i;
00308                 perm[i__3].r = q__1.r, perm[i__3].i = q__1.i;
00309 /* L210: */
00310             }
00311             i__2 = j + j * perm_dim1;
00312             i__3 = j + j * perm_dim1;
00313             i__4 = j + j * a_dim1;
00314             r__1 = a[i__4].r;
00315             q__1.r = perm[i__3].r - r__1, q__1.i = perm[i__3].i;
00316             perm[i__2].r = q__1.r, perm[i__2].i = q__1.i;
00317 /* L220: */
00318         }
00319     } else {
00320         i__1 = *n;
00321         for (j = 1; j <= i__1; ++j) {
00322             i__2 = j + j * perm_dim1;
00323             i__3 = j + j * perm_dim1;
00324             i__4 = j + j * a_dim1;
00325             r__1 = a[i__4].r;
00326             q__1.r = perm[i__3].r - r__1, q__1.i = perm[i__3].i;
00327             perm[i__2].r = q__1.r, perm[i__2].i = q__1.i;
00328             i__2 = *n;
00329             for (i__ = j + 1; i__ <= i__2; ++i__) {
00330                 i__3 = i__ + j * perm_dim1;
00331                 i__4 = i__ + j * perm_dim1;
00332                 i__5 = i__ + j * a_dim1;
00333                 q__1.r = perm[i__4].r - a[i__5].r, q__1.i = perm[i__4].i - a[
00334                         i__5].i;
00335                 perm[i__3].r = q__1.r, perm[i__3].i = q__1.i;
00336 /* L230: */
00337             }
00338 /* L240: */
00339         }
00340     }
00341 
00342 /*     Compute norm( P*L*L'P - A ) / ( N * norm(A) * EPS ), or */
00343 /*     ( P*U'*U*P' - A )/ ( N * norm(A) * EPS ). */
00344 
00345     *resid = clanhe_("1", uplo, n, &perm[perm_offset], ldafac, &rwork[1]);
00346 
00347     *resid = *resid / (real) (*n) / anorm / eps;
00348 
00349     return 0;
00350 
00351 /*     End of CPST01 */
00352 
00353 } /* cpst01_ */


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