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


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