spst01.c
Go to the documentation of this file.
00001 /* spst01.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_b18 = 1.f;
00020 
00021 /* Subroutine */ int spst01_(char *uplo, integer *n, real *a, integer *lda, 
00022         real *afac, integer *ldafac, real *perm, integer *ldperm, integer *
00023         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;
00028 
00029     /* Local variables */
00030     integer i__, j, k;
00031     real t, eps;
00032     extern doublereal sdot_(integer *, real *, integer *, real *, integer *);
00033     extern /* Subroutine */ int ssyr_(char *, integer *, real *, real *, 
00034             integer *, real *, integer *);
00035     extern logical lsame_(char *, char *);
00036     extern /* Subroutine */ int sscal_(integer *, real *, real *, integer *);
00037     real anorm;
00038     extern /* Subroutine */ int strmv_(char *, char *, char *, integer *, 
00039             real *, integer *, real *, integer *);
00040     extern doublereal slamch_(char *), slansy_(char *, char *, 
00041             integer *, real *, integer *, real *);
00042 
00043 
00044 /*  -- LAPACK test routine (version 3.1) -- */
00045 /*     Craig Lucas, University of Manchester / NAG Ltd. */
00046 /*     October, 2008 */
00047 
00048 /*     .. Scalar Arguments .. */
00049 /*     .. */
00050 /*     .. Array Arguments .. */
00051 /*     .. */
00052 
00053 /*  Purpose */
00054 /*  ======= */
00055 
00056 /*  SPST01 reconstructs a symmetric positive semidefinite matrix A */
00057 /*  from its L or U factors and the permutation matrix P and computes */
00058 /*  the residual */
00059 /*     norm( P*L*L'*P' - A ) / ( N * norm(A) * EPS ) or */
00060 /*     norm( P*U'*U*P' - A ) / ( N * norm(A) * EPS ), */
00061 /*  where EPS is the machine epsilon. */
00062 
00063 /*  Arguments */
00064 /*  ========== */
00065 
00066 /*  UPLO    (input) CHARACTER*1 */
00067 /*          Specifies whether the upper or lower triangular part of the */
00068 /*          symmetric matrix A is stored: */
00069 /*          = 'U':  Upper triangular */
00070 /*          = 'L':  Lower triangular */
00071 
00072 /*  N       (input) INTEGER */
00073 /*          The number of rows and columns of the matrix A.  N >= 0. */
00074 
00075 /*  A       (input) REAL array, dimension (LDA,N) */
00076 /*          The original symmetric matrix A. */
00077 
00078 /*  LDA     (input) INTEGER */
00079 /*          The leading dimension of the array A.  LDA >= max(1,N) */
00080 
00081 /*  AFAC    (input) REAL array, dimension (LDAFAC,N) */
00082 /*          The factor L or U from the L*L' or U'*U */
00083 /*          factorization of A. */
00084 
00085 /*  LDAFAC  (input) INTEGER */
00086 /*          The leading dimension of the array AFAC.  LDAFAC >= max(1,N). */
00087 
00088 /*  PERM    (output) REAL array, dimension (LDPERM,N) */
00089 /*          Overwritten with the reconstructed matrix, and then with the */
00090 /*          difference P*L*L'*P' - A (or P*U'*U*P' - A) */
00091 
00092 /*  LDPERM  (input) INTEGER */
00093 /*          The leading dimension of the array PERM. */
00094 /*          LDAPERM >= max(1,N). */
00095 
00096 /*  PIV     (input) INTEGER array, dimension (N) */
00097 /*          PIV is such that the nonzero entries are */
00098 /*          P( PIV( K ), K ) = 1. */
00099 
00100 /*  RWORK   (workspace) REAL array, dimension (N) */
00101 
00102 /*  RESID   (output) REAL */
00103 /*          If UPLO = 'L', norm(L*L' - A) / ( N * norm(A) * EPS ) */
00104 /*          If UPLO = 'U', norm(U'*U - A) / ( N * norm(A) * EPS ) */
00105 
00106 /*  ===================================================================== */
00107 
00108 /*     .. Parameters .. */
00109 /*     .. */
00110 /*     .. Local Scalars .. */
00111 /*     .. */
00112 /*     .. External Functions .. */
00113 /*     .. */
00114 /*     .. External Subroutines .. */
00115 /*     .. */
00116 /*     .. Intrinsic Functions .. */
00117 /*     .. */
00118 /*     .. Executable Statements .. */
00119 
00120 /*     Quick exit if N = 0. */
00121 
00122     /* Parameter adjustments */
00123     a_dim1 = *lda;
00124     a_offset = 1 + a_dim1;
00125     a -= a_offset;
00126     afac_dim1 = *ldafac;
00127     afac_offset = 1 + afac_dim1;
00128     afac -= afac_offset;
00129     perm_dim1 = *ldperm;
00130     perm_offset = 1 + perm_dim1;
00131     perm -= perm_offset;
00132     --piv;
00133     --rwork;
00134 
00135     /* Function Body */
00136     if (*n <= 0) {
00137         *resid = 0.f;
00138         return 0;
00139     }
00140 
00141 /*     Exit with RESID = 1/EPS if ANORM = 0. */
00142 
00143     eps = slamch_("Epsilon");
00144     anorm = slansy_("1", uplo, n, &a[a_offset], lda, &rwork[1]);
00145     if (anorm <= 0.f) {
00146         *resid = 1.f / eps;
00147         return 0;
00148     }
00149 
00150 /*     Compute the product U'*U, overwriting U. */
00151 
00152     if (lsame_(uplo, "U")) {
00153 
00154         if (*rank < *n) {
00155             i__1 = *n;
00156             for (j = *rank + 1; j <= i__1; ++j) {
00157                 i__2 = j;
00158                 for (i__ = *rank + 1; i__ <= i__2; ++i__) {
00159                     afac[i__ + j * afac_dim1] = 0.f;
00160 /* L100: */
00161                 }
00162 /* L110: */
00163             }
00164         }
00165 
00166         for (k = *n; k >= 1; --k) {
00167 
00168 /*           Compute the (K,K) element of the result. */
00169 
00170             t = sdot_(&k, &afac[k * afac_dim1 + 1], &c__1, &afac[k * 
00171                     afac_dim1 + 1], &c__1);
00172             afac[k + k * afac_dim1] = t;
00173 
00174 /*           Compute the rest of column K. */
00175 
00176             i__1 = k - 1;
00177             strmv_("Upper", "Transpose", "Non-unit", &i__1, &afac[afac_offset]
00178 , ldafac, &afac[k * afac_dim1 + 1], &c__1);
00179 
00180 /* L120: */
00181         }
00182 
00183 /*     Compute the product L*L', overwriting L. */
00184 
00185     } else {
00186 
00187         if (*rank < *n) {
00188             i__1 = *n;
00189             for (j = *rank + 1; j <= i__1; ++j) {
00190                 i__2 = *n;
00191                 for (i__ = j; i__ <= i__2; ++i__) {
00192                     afac[i__ + j * afac_dim1] = 0.f;
00193 /* L130: */
00194                 }
00195 /* L140: */
00196             }
00197         }
00198 
00199         for (k = *n; k >= 1; --k) {
00200 /*           Add a multiple of column K of the factor L to each of */
00201 /*           columns K+1 through N. */
00202 
00203             if (k + 1 <= *n) {
00204                 i__1 = *n - k;
00205                 ssyr_("Lower", &i__1, &c_b18, &afac[k + 1 + k * afac_dim1], &
00206                         c__1, &afac[k + 1 + (k + 1) * afac_dim1], ldafac);
00207             }
00208 
00209 /*           Scale column K by the diagonal element. */
00210 
00211             t = afac[k + k * afac_dim1];
00212             i__1 = *n - k + 1;
00213             sscal_(&i__1, &t, &afac[k + k * afac_dim1], &c__1);
00214 /* L150: */
00215         }
00216 
00217     }
00218 
00219 /*        Form P*L*L'*P' or P*U'*U*P' */
00220 
00221     if (lsame_(uplo, "U")) {
00222 
00223         i__1 = *n;
00224         for (j = 1; j <= i__1; ++j) {
00225             i__2 = *n;
00226             for (i__ = 1; i__ <= i__2; ++i__) {
00227                 if (piv[i__] <= piv[j]) {
00228                     if (i__ <= j) {
00229                         perm[piv[i__] + piv[j] * perm_dim1] = afac[i__ + j * 
00230                                 afac_dim1];
00231                     } else {
00232                         perm[piv[i__] + piv[j] * perm_dim1] = afac[j + i__ * 
00233                                 afac_dim1];
00234                     }
00235                 }
00236 /* L160: */
00237             }
00238 /* L170: */
00239         }
00240 
00241 
00242     } else {
00243 
00244         i__1 = *n;
00245         for (j = 1; j <= i__1; ++j) {
00246             i__2 = *n;
00247             for (i__ = 1; i__ <= i__2; ++i__) {
00248                 if (piv[i__] >= piv[j]) {
00249                     if (i__ >= j) {
00250                         perm[piv[i__] + piv[j] * perm_dim1] = afac[i__ + j * 
00251                                 afac_dim1];
00252                     } else {
00253                         perm[piv[i__] + piv[j] * perm_dim1] = afac[j + i__ * 
00254                                 afac_dim1];
00255                     }
00256                 }
00257 /* L180: */
00258             }
00259 /* L190: */
00260         }
00261 
00262     }
00263 
00264 /*     Compute the difference  P*L*L'*P' - A (or P*U'*U*P' - A). */
00265 
00266     if (lsame_(uplo, "U")) {
00267         i__1 = *n;
00268         for (j = 1; j <= i__1; ++j) {
00269             i__2 = j;
00270             for (i__ = 1; i__ <= i__2; ++i__) {
00271                 perm[i__ + j * perm_dim1] -= a[i__ + j * a_dim1];
00272 /* L200: */
00273             }
00274 /* L210: */
00275         }
00276     } else {
00277         i__1 = *n;
00278         for (j = 1; j <= i__1; ++j) {
00279             i__2 = *n;
00280             for (i__ = j; i__ <= i__2; ++i__) {
00281                 perm[i__ + j * perm_dim1] -= a[i__ + j * a_dim1];
00282 /* L220: */
00283             }
00284 /* L230: */
00285         }
00286     }
00287 
00288 /*     Compute norm( P*L*L'P - A ) / ( N * norm(A) * EPS ), or */
00289 /*     ( P*U'*U*P' - A )/ ( N * norm(A) * EPS ). */
00290 
00291     *resid = slansy_("1", uplo, n, &perm[perm_offset], ldafac, &rwork[1]);
00292 
00293     *resid = *resid / (real) (*n) / anorm / eps;
00294 
00295     return 0;
00296 
00297 /*     End of SPST01 */
00298 
00299 } /* spst01_ */


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