00001 /* spftrf.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 real c_b12 = 1.f; 00019 static real c_b15 = -1.f; 00020 00021 /* Subroutine */ int spftrf_(char *transr, char *uplo, integer *n, real *a, 00022 integer *info) 00023 { 00024 /* System generated locals */ 00025 integer i__1, i__2; 00026 00027 /* Local variables */ 00028 integer k, n1, n2; 00029 logical normaltransr; 00030 extern logical lsame_(char *, char *); 00031 logical lower; 00032 extern /* Subroutine */ int strsm_(char *, char *, char *, char *, 00033 integer *, integer *, real *, real *, integer *, real *, integer * 00034 ), ssyrk_(char *, char *, integer 00035 *, integer *, real *, real *, integer *, real *, real *, integer * 00036 ), xerbla_(char *, integer *); 00037 logical nisodd; 00038 extern /* Subroutine */ int spotrf_(char *, integer *, real *, integer *, 00039 integer *); 00040 00041 00042 /* -- LAPACK routine (version 3.2) -- */ 00043 00044 /* -- Contributed by Fred Gustavson of the IBM Watson Research Center -- */ 00045 /* -- November 2008 -- */ 00046 00047 /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */ 00048 /* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */ 00049 00050 /* .. */ 00051 /* .. Scalar Arguments .. */ 00052 /* .. */ 00053 /* .. Array Arguments .. */ 00054 00055 /* Purpose */ 00056 /* ======= */ 00057 00058 /* SPFTRF computes the Cholesky factorization of a real symmetric */ 00059 /* positive definite matrix A. */ 00060 00061 /* The factorization has the form */ 00062 /* A = U**T * U, if UPLO = 'U', or */ 00063 /* A = L * L**T, if UPLO = 'L', */ 00064 /* where U is an upper triangular matrix and L is lower triangular. */ 00065 00066 /* This is the block version of the algorithm, calling Level 3 BLAS. */ 00067 00068 /* Arguments */ 00069 /* ========= */ 00070 00071 /* TRANSR (input) CHARACTER */ 00072 /* = 'N': The Normal TRANSR of RFP A is stored; */ 00073 /* = 'T': The Transpose TRANSR of RFP A is stored. */ 00074 00075 /* UPLO (input) CHARACTER */ 00076 /* = 'U': Upper triangle of RFP A is stored; */ 00077 /* = 'L': Lower triangle of RFP A is stored. */ 00078 00079 /* N (input) INTEGER */ 00080 /* The order of the matrix A. N >= 0. */ 00081 00082 /* A (input/output) REAL array, dimension ( N*(N+1)/2 ); */ 00083 /* On entry, the symmetric matrix A in RFP format. RFP format is */ 00084 /* described by TRANSR, UPLO, and N as follows: If TRANSR = 'N' */ 00085 /* then RFP A is (0:N,0:k-1) when N is even; k=N/2. RFP A is */ 00086 /* (0:N-1,0:k) when N is odd; k=N/2. IF TRANSR = 'T' then RFP is */ 00087 /* the transpose of RFP A as defined when */ 00088 /* TRANSR = 'N'. The contents of RFP A are defined by UPLO as */ 00089 /* follows: If UPLO = 'U' the RFP A contains the NT elements of */ 00090 /* upper packed A. If UPLO = 'L' the RFP A contains the elements */ 00091 /* of lower packed A. The LDA of RFP A is (N+1)/2 when TRANSR = */ 00092 /* 'T'. When TRANSR is 'N' the LDA is N+1 when N is even and N */ 00093 /* is odd. See the Note below for more details. */ 00094 00095 /* On exit, if INFO = 0, the factor U or L from the Cholesky */ 00096 /* factorization RFP A = U**T*U or RFP A = L*L**T. */ 00097 00098 /* INFO (output) INTEGER */ 00099 /* = 0: successful exit */ 00100 /* < 0: if INFO = -i, the i-th argument had an illegal value */ 00101 /* > 0: if INFO = i, the leading minor of order i is not */ 00102 /* positive definite, and the factorization could not be */ 00103 /* completed. */ 00104 00105 /* Notes */ 00106 /* ===== */ 00107 00108 /* We first consider Rectangular Full Packed (RFP) Format when N is */ 00109 /* even. We give an example where N = 6. */ 00110 00111 /* AP is Upper AP is Lower */ 00112 00113 /* 00 01 02 03 04 05 00 */ 00114 /* 11 12 13 14 15 10 11 */ 00115 /* 22 23 24 25 20 21 22 */ 00116 /* 33 34 35 30 31 32 33 */ 00117 /* 44 45 40 41 42 43 44 */ 00118 /* 55 50 51 52 53 54 55 */ 00119 00120 00121 /* Let TRANSR = 'N'. RFP holds AP as follows: */ 00122 /* For UPLO = 'U' the upper trapezoid A(0:5,0:2) consists of the last */ 00123 /* three columns of AP upper. The lower triangle A(4:6,0:2) consists of */ 00124 /* the transpose of the first three columns of AP upper. */ 00125 /* For UPLO = 'L' the lower trapezoid A(1:6,0:2) consists of the first */ 00126 /* three columns of AP lower. The upper triangle A(0:2,0:2) consists of */ 00127 /* the transpose of the last three columns of AP lower. */ 00128 /* This covers the case N even and TRANSR = 'N'. */ 00129 00130 /* RFP A RFP A */ 00131 00132 /* 03 04 05 33 43 53 */ 00133 /* 13 14 15 00 44 54 */ 00134 /* 23 24 25 10 11 55 */ 00135 /* 33 34 35 20 21 22 */ 00136 /* 00 44 45 30 31 32 */ 00137 /* 01 11 55 40 41 42 */ 00138 /* 02 12 22 50 51 52 */ 00139 00140 /* Now let TRANSR = 'T'. RFP A in both UPLO cases is just the */ 00141 /* transpose of RFP A above. One therefore gets: */ 00142 00143 00144 /* RFP A RFP A */ 00145 00146 /* 03 13 23 33 00 01 02 33 00 10 20 30 40 50 */ 00147 /* 04 14 24 34 44 11 12 43 44 11 21 31 41 51 */ 00148 /* 05 15 25 35 45 55 22 53 54 55 22 32 42 52 */ 00149 00150 00151 /* We first consider Rectangular Full Packed (RFP) Format when N is */ 00152 /* odd. We give an example where N = 5. */ 00153 00154 /* AP is Upper AP is Lower */ 00155 00156 /* 00 01 02 03 04 00 */ 00157 /* 11 12 13 14 10 11 */ 00158 /* 22 23 24 20 21 22 */ 00159 /* 33 34 30 31 32 33 */ 00160 /* 44 40 41 42 43 44 */ 00161 00162 00163 /* Let TRANSR = 'N'. RFP holds AP as follows: */ 00164 /* For UPLO = 'U' the upper trapezoid A(0:4,0:2) consists of the last */ 00165 /* three columns of AP upper. The lower triangle A(3:4,0:1) consists of */ 00166 /* the transpose of the first two columns of AP upper. */ 00167 /* For UPLO = 'L' the lower trapezoid A(0:4,0:2) consists of the first */ 00168 /* three columns of AP lower. The upper triangle A(0:1,1:2) consists of */ 00169 /* the transpose of the last two columns of AP lower. */ 00170 /* This covers the case N odd and TRANSR = 'N'. */ 00171 00172 /* RFP A RFP A */ 00173 00174 /* 02 03 04 00 33 43 */ 00175 /* 12 13 14 10 11 44 */ 00176 /* 22 23 24 20 21 22 */ 00177 /* 00 33 34 30 31 32 */ 00178 /* 01 11 44 40 41 42 */ 00179 00180 /* Now let TRANSR = 'T'. RFP A in both UPLO cases is just the */ 00181 /* transpose of RFP A above. One therefore gets: */ 00182 00183 /* RFP A RFP A */ 00184 00185 /* 02 12 22 00 01 00 10 20 30 40 50 */ 00186 /* 03 13 23 33 11 33 11 21 31 41 51 */ 00187 /* 04 14 24 34 44 43 44 22 32 42 52 */ 00188 00189 /* ===================================================================== */ 00190 00191 /* .. Parameters .. */ 00192 /* .. */ 00193 /* .. Local Scalars .. */ 00194 /* .. */ 00195 /* .. External Functions .. */ 00196 /* .. */ 00197 /* .. External Subroutines .. */ 00198 /* .. */ 00199 /* .. Intrinsic Functions .. */ 00200 /* .. */ 00201 /* .. Executable Statements .. */ 00202 00203 /* Test the input parameters. */ 00204 00205 *info = 0; 00206 normaltransr = lsame_(transr, "N"); 00207 lower = lsame_(uplo, "L"); 00208 if (! normaltransr && ! lsame_(transr, "T")) { 00209 *info = -1; 00210 } else if (! lower && ! lsame_(uplo, "U")) { 00211 *info = -2; 00212 } else if (*n < 0) { 00213 *info = -3; 00214 } 00215 if (*info != 0) { 00216 i__1 = -(*info); 00217 xerbla_("SPFTRF", &i__1); 00218 return 0; 00219 } 00220 00221 /* Quick return if possible */ 00222 00223 if (*n == 0) { 00224 return 0; 00225 } 00226 00227 /* If N is odd, set NISODD = .TRUE. */ 00228 /* If N is even, set K = N/2 and NISODD = .FALSE. */ 00229 00230 if (*n % 2 == 0) { 00231 k = *n / 2; 00232 nisodd = FALSE_; 00233 } else { 00234 nisodd = TRUE_; 00235 } 00236 00237 /* Set N1 and N2 depending on LOWER */ 00238 00239 if (lower) { 00240 n2 = *n / 2; 00241 n1 = *n - n2; 00242 } else { 00243 n1 = *n / 2; 00244 n2 = *n - n1; 00245 } 00246 00247 /* start execution: there are eight cases */ 00248 00249 if (nisodd) { 00250 00251 /* N is odd */ 00252 00253 if (normaltransr) { 00254 00255 /* N is odd and TRANSR = 'N' */ 00256 00257 if (lower) { 00258 00259 /* SRPA for LOWER, NORMAL and N is odd ( a(0:n-1,0:n1-1) ) */ 00260 /* T1 -> a(0,0), T2 -> a(0,1), S -> a(n1,0) */ 00261 /* T1 -> a(0), T2 -> a(n), S -> a(n1) */ 00262 00263 spotrf_("L", &n1, a, n, info); 00264 if (*info > 0) { 00265 return 0; 00266 } 00267 strsm_("R", "L", "T", "N", &n2, &n1, &c_b12, a, n, &a[n1], n); 00268 ssyrk_("U", "N", &n2, &n1, &c_b15, &a[n1], n, &c_b12, &a[*n], 00269 n); 00270 spotrf_("U", &n2, &a[*n], n, info); 00271 if (*info > 0) { 00272 *info += n1; 00273 } 00274 00275 } else { 00276 00277 /* SRPA for UPPER, NORMAL and N is odd ( a(0:n-1,0:n2-1) */ 00278 /* T1 -> a(n1+1,0), T2 -> a(n1,0), S -> a(0,0) */ 00279 /* T1 -> a(n2), T2 -> a(n1), S -> a(0) */ 00280 00281 spotrf_("L", &n1, &a[n2], n, info); 00282 if (*info > 0) { 00283 return 0; 00284 } 00285 strsm_("L", "L", "N", "N", &n1, &n2, &c_b12, &a[n2], n, a, n); 00286 ssyrk_("U", "T", &n2, &n1, &c_b15, a, n, &c_b12, &a[n1], n); 00287 spotrf_("U", &n2, &a[n1], n, info); 00288 if (*info > 0) { 00289 *info += n1; 00290 } 00291 00292 } 00293 00294 } else { 00295 00296 /* N is odd and TRANSR = 'T' */ 00297 00298 if (lower) { 00299 00300 /* SRPA for LOWER, TRANSPOSE and N is odd */ 00301 /* T1 -> A(0,0) , T2 -> A(1,0) , S -> A(0,n1) */ 00302 /* T1 -> a(0+0) , T2 -> a(1+0) , S -> a(0+n1*n1); lda=n1 */ 00303 00304 spotrf_("U", &n1, a, &n1, info); 00305 if (*info > 0) { 00306 return 0; 00307 } 00308 strsm_("L", "U", "T", "N", &n1, &n2, &c_b12, a, &n1, &a[n1 * 00309 n1], &n1); 00310 ssyrk_("L", "T", &n2, &n1, &c_b15, &a[n1 * n1], &n1, &c_b12, & 00311 a[1], &n1); 00312 spotrf_("L", &n2, &a[1], &n1, info); 00313 if (*info > 0) { 00314 *info += n1; 00315 } 00316 00317 } else { 00318 00319 /* SRPA for UPPER, TRANSPOSE and N is odd */ 00320 /* T1 -> A(0,n1+1), T2 -> A(0,n1), S -> A(0,0) */ 00321 /* T1 -> a(n2*n2), T2 -> a(n1*n2), S -> a(0); lda = n2 */ 00322 00323 spotrf_("U", &n1, &a[n2 * n2], &n2, info); 00324 if (*info > 0) { 00325 return 0; 00326 } 00327 strsm_("R", "U", "N", "N", &n2, &n1, &c_b12, &a[n2 * n2], &n2, 00328 a, &n2); 00329 ssyrk_("L", "N", &n2, &n1, &c_b15, a, &n2, &c_b12, &a[n1 * n2] 00330 , &n2); 00331 spotrf_("L", &n2, &a[n1 * n2], &n2, info); 00332 if (*info > 0) { 00333 *info += n1; 00334 } 00335 00336 } 00337 00338 } 00339 00340 } else { 00341 00342 /* N is even */ 00343 00344 if (normaltransr) { 00345 00346 /* N is even and TRANSR = 'N' */ 00347 00348 if (lower) { 00349 00350 /* SRPA for LOWER, NORMAL, and N is even ( a(0:n,0:k-1) ) */ 00351 /* T1 -> a(1,0), T2 -> a(0,0), S -> a(k+1,0) */ 00352 /* T1 -> a(1), T2 -> a(0), S -> a(k+1) */ 00353 00354 i__1 = *n + 1; 00355 spotrf_("L", &k, &a[1], &i__1, info); 00356 if (*info > 0) { 00357 return 0; 00358 } 00359 i__1 = *n + 1; 00360 i__2 = *n + 1; 00361 strsm_("R", "L", "T", "N", &k, &k, &c_b12, &a[1], &i__1, &a[k 00362 + 1], &i__2); 00363 i__1 = *n + 1; 00364 i__2 = *n + 1; 00365 ssyrk_("U", "N", &k, &k, &c_b15, &a[k + 1], &i__1, &c_b12, a, 00366 &i__2); 00367 i__1 = *n + 1; 00368 spotrf_("U", &k, a, &i__1, info); 00369 if (*info > 0) { 00370 *info += k; 00371 } 00372 00373 } else { 00374 00375 /* SRPA for UPPER, NORMAL, and N is even ( a(0:n,0:k-1) ) */ 00376 /* T1 -> a(k+1,0) , T2 -> a(k,0), S -> a(0,0) */ 00377 /* T1 -> a(k+1), T2 -> a(k), S -> a(0) */ 00378 00379 i__1 = *n + 1; 00380 spotrf_("L", &k, &a[k + 1], &i__1, info); 00381 if (*info > 0) { 00382 return 0; 00383 } 00384 i__1 = *n + 1; 00385 i__2 = *n + 1; 00386 strsm_("L", "L", "N", "N", &k, &k, &c_b12, &a[k + 1], &i__1, 00387 a, &i__2); 00388 i__1 = *n + 1; 00389 i__2 = *n + 1; 00390 ssyrk_("U", "T", &k, &k, &c_b15, a, &i__1, &c_b12, &a[k], & 00391 i__2); 00392 i__1 = *n + 1; 00393 spotrf_("U", &k, &a[k], &i__1, info); 00394 if (*info > 0) { 00395 *info += k; 00396 } 00397 00398 } 00399 00400 } else { 00401 00402 /* N is even and TRANSR = 'T' */ 00403 00404 if (lower) { 00405 00406 /* SRPA for LOWER, TRANSPOSE and N is even (see paper) */ 00407 /* T1 -> B(0,1), T2 -> B(0,0), S -> B(0,k+1) */ 00408 /* T1 -> a(0+k), T2 -> a(0+0), S -> a(0+k*(k+1)); lda=k */ 00409 00410 spotrf_("U", &k, &a[k], &k, info); 00411 if (*info > 0) { 00412 return 0; 00413 } 00414 strsm_("L", "U", "T", "N", &k, &k, &c_b12, &a[k], &n1, &a[k * 00415 (k + 1)], &k); 00416 ssyrk_("L", "T", &k, &k, &c_b15, &a[k * (k + 1)], &k, &c_b12, 00417 a, &k); 00418 spotrf_("L", &k, a, &k, info); 00419 if (*info > 0) { 00420 *info += k; 00421 } 00422 00423 } else { 00424 00425 /* SRPA for UPPER, TRANSPOSE and N is even (see paper) */ 00426 /* T1 -> B(0,k+1), T2 -> B(0,k), S -> B(0,0) */ 00427 /* T1 -> a(0+k*(k+1)), T2 -> a(0+k*k), S -> a(0+0)); lda=k */ 00428 00429 spotrf_("U", &k, &a[k * (k + 1)], &k, info); 00430 if (*info > 0) { 00431 return 0; 00432 } 00433 strsm_("R", "U", "N", "N", &k, &k, &c_b12, &a[k * (k + 1)], & 00434 k, a, &k); 00435 ssyrk_("L", "N", &k, &k, &c_b15, a, &k, &c_b12, &a[k * k], &k); 00436 spotrf_("L", &k, &a[k * k], &k, info); 00437 if (*info > 0) { 00438 *info += k; 00439 } 00440 00441 } 00442 00443 } 00444 00445 } 00446 00447 return 0; 00448 00449 /* End of SPFTRF */ 00450 00451 } /* spftrf_ */