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