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