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