00001 /* sppt01.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_b14 = 1.f; 00020 00021 /* Subroutine */ int sppt01_(char *uplo, integer *n, real *a, real *afac, 00022 real *rwork, real *resid) 00023 { 00024 /* System generated locals */ 00025 integer i__1; 00026 00027 /* Local variables */ 00028 integer i__, k; 00029 real t; 00030 integer kc; 00031 real eps; 00032 integer npp; 00033 extern doublereal sdot_(integer *, real *, integer *, real *, integer *); 00034 extern /* Subroutine */ int sspr_(char *, integer *, real *, real *, 00035 integer *, real *); 00036 extern logical lsame_(char *, char *); 00037 extern /* Subroutine */ int sscal_(integer *, real *, real *, integer *); 00038 real anorm; 00039 extern /* Subroutine */ int stpmv_(char *, char *, char *, integer *, 00040 real *, real *, integer *); 00041 extern doublereal slamch_(char *), slansp_(char *, char *, 00042 integer *, real *, real *); 00043 00044 00045 /* -- LAPACK test routine (version 3.1) -- */ 00046 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ 00047 /* November 2006 */ 00048 00049 /* .. Scalar Arguments .. */ 00050 /* .. */ 00051 /* .. Array Arguments .. */ 00052 /* .. */ 00053 00054 /* Purpose */ 00055 /* ======= */ 00056 00057 /* SPPT01 reconstructs a symmetric positive definite packed matrix A */ 00058 /* from its L*L' or U'*U factorization and computes the residual */ 00059 /* norm( L*L' - A ) / ( N * norm(A) * EPS ) or */ 00060 /* norm( U'*U - 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 (N*(N+1)/2) */ 00076 /* The original symmetric matrix A, stored as a packed */ 00077 /* triangular matrix. */ 00078 00079 /* AFAC (input/output) REAL array, dimension (N*(N+1)/2) */ 00080 /* On entry, the factor L or U from the L*L' or U'*U */ 00081 /* factorization of A, stored as a packed triangular matrix. */ 00082 /* Overwritten with the reconstructed matrix, and then with the */ 00083 /* difference L*L' - A (or U'*U - A). */ 00084 00085 /* RWORK (workspace) REAL array, dimension (N) */ 00086 00087 /* RESID (output) REAL */ 00088 /* If UPLO = 'L', norm(L*L' - A) / ( N * norm(A) * EPS ) */ 00089 /* If UPLO = 'U', norm(U'*U - A) / ( N * norm(A) * EPS ) */ 00090 00091 /* ===================================================================== */ 00092 00093 /* .. Parameters .. */ 00094 /* .. */ 00095 /* .. Local Scalars .. */ 00096 /* .. */ 00097 /* .. External Functions .. */ 00098 /* .. */ 00099 /* .. External Subroutines .. */ 00100 /* .. */ 00101 /* .. Intrinsic Functions .. */ 00102 /* .. */ 00103 /* .. Executable Statements .. */ 00104 00105 /* Quick exit if N = 0 */ 00106 00107 /* Parameter adjustments */ 00108 --rwork; 00109 --afac; 00110 --a; 00111 00112 /* Function Body */ 00113 if (*n <= 0) { 00114 *resid = 0.f; 00115 return 0; 00116 } 00117 00118 /* Exit with RESID = 1/EPS if ANORM = 0. */ 00119 00120 eps = slamch_("Epsilon"); 00121 anorm = slansp_("1", uplo, n, &a[1], &rwork[1]); 00122 if (anorm <= 0.f) { 00123 *resid = 1.f / eps; 00124 return 0; 00125 } 00126 00127 /* Compute the product U'*U, overwriting U. */ 00128 00129 if (lsame_(uplo, "U")) { 00130 kc = *n * (*n - 1) / 2 + 1; 00131 for (k = *n; k >= 1; --k) { 00132 00133 /* Compute the (K,K) element of the result. */ 00134 00135 t = sdot_(&k, &afac[kc], &c__1, &afac[kc], &c__1); 00136 afac[kc + k - 1] = t; 00137 00138 /* Compute the rest of column K. */ 00139 00140 if (k > 1) { 00141 i__1 = k - 1; 00142 stpmv_("Upper", "Transpose", "Non-unit", &i__1, &afac[1], & 00143 afac[kc], &c__1); 00144 kc -= k - 1; 00145 } 00146 /* L10: */ 00147 } 00148 00149 /* Compute the product L*L', overwriting L. */ 00150 00151 } else { 00152 kc = *n * (*n + 1) / 2; 00153 for (k = *n; k >= 1; --k) { 00154 00155 /* Add a multiple of column K of the factor L to each of */ 00156 /* columns K+1 through N. */ 00157 00158 if (k < *n) { 00159 i__1 = *n - k; 00160 sspr_("Lower", &i__1, &c_b14, &afac[kc + 1], &c__1, &afac[kc 00161 + *n - k + 1]); 00162 } 00163 00164 /* Scale column K by the diagonal element. */ 00165 00166 t = afac[kc]; 00167 i__1 = *n - k + 1; 00168 sscal_(&i__1, &t, &afac[kc], &c__1); 00169 00170 kc -= *n - k + 2; 00171 /* L20: */ 00172 } 00173 } 00174 00175 /* Compute the difference L*L' - A (or U'*U - A). */ 00176 00177 npp = *n * (*n + 1) / 2; 00178 i__1 = npp; 00179 for (i__ = 1; i__ <= i__1; ++i__) { 00180 afac[i__] -= a[i__]; 00181 /* L30: */ 00182 } 00183 00184 /* Compute norm( L*U - A ) / ( N * norm(A) * EPS ) */ 00185 00186 *resid = slansp_("1", uplo, n, &afac[1], &rwork[1]); 00187 00188 *resid = *resid / (real) (*n) / anorm / eps; 00189 00190 return 0; 00191 00192 /* End of SPPT01 */ 00193 00194 } /* sppt01_ */