00001 /* dtftri.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 doublereal c_b13 = -1.; 00019 static doublereal c_b18 = 1.; 00020 00021 /* Subroutine */ int dtftri_(char *transr, char *uplo, char *diag, integer *n, 00022 doublereal *a, 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 extern /* Subroutine */ int dtrmm_(char *, char *, char *, char *, 00032 integer *, integer *, doublereal *, doublereal *, integer *, 00033 doublereal *, integer *); 00034 logical lower; 00035 extern /* Subroutine */ int xerbla_(char *, integer *); 00036 logical nisodd; 00037 extern /* Subroutine */ int dtrtri_(char *, char *, integer *, doublereal 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 /* DTFTRI 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 /* = 'T': The 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) DOUBLE PRECISION array, dimension (0:nt-1); */ 00081 /* nt=N*(N+1)/2. On entry, the triangular factor of a Hermitian */ 00082 /* Positive Definite matrix A in RFP format. RFP format is */ 00083 /* described by TRANSR, UPLO, and N as follows: If TRANSR = 'N' */ 00084 /* then RFP A is (0:N,0:k-1) when N is even; k=N/2. RFP A is */ 00085 /* (0:N-1,0:k) when N is odd; k=N/2. IF TRANSR = 'T' then RFP is */ 00086 /* the transpose of RFP A as defined when */ 00087 /* TRANSR = 'N'. The contents of RFP A are defined by UPLO as */ 00088 /* follows: If UPLO = 'U' the RFP A contains the nt elements of */ 00089 /* upper packed A; If UPLO = 'L' the RFP A contains the nt */ 00090 /* elements of lower packed A. The LDA of RFP A is (N+1)/2 when */ 00091 /* TRANSR = 'T'. When TRANSR is 'N' the LDA is N+1 when N is */ 00092 /* even and N is odd. See the Note below for more details. */ 00093 00094 /* On exit, the (triangular) inverse of the original matrix, in */ 00095 /* the same storage format. */ 00096 00097 /* INFO (output) INTEGER */ 00098 /* = 0: successful exit */ 00099 /* < 0: if INFO = -i, the i-th argument had an illegal value */ 00100 /* > 0: if INFO = i, A(i,i) is exactly zero. The triangular */ 00101 /* matrix is singular and its inverse can not be computed. */ 00102 00103 /* Notes */ 00104 /* ===== */ 00105 00106 /* We first consider Rectangular Full Packed (RFP) Format when N is */ 00107 /* even. We give an example where N = 6. */ 00108 00109 /* AP is Upper AP is Lower */ 00110 00111 /* 00 01 02 03 04 05 00 */ 00112 /* 11 12 13 14 15 10 11 */ 00113 /* 22 23 24 25 20 21 22 */ 00114 /* 33 34 35 30 31 32 33 */ 00115 /* 44 45 40 41 42 43 44 */ 00116 /* 55 50 51 52 53 54 55 */ 00117 00118 00119 /* Let TRANSR = 'N'. RFP holds AP as follows: */ 00120 /* For UPLO = 'U' the upper trapezoid A(0:5,0:2) consists of the last */ 00121 /* three columns of AP upper. The lower triangle A(4:6,0:2) consists of */ 00122 /* the transpose of the first three columns of AP upper. */ 00123 /* For UPLO = 'L' the lower trapezoid A(1:6,0:2) consists of the first */ 00124 /* three columns of AP lower. The upper triangle A(0:2,0:2) consists of */ 00125 /* the transpose of the last three columns of AP lower. */ 00126 /* This covers the case N even and TRANSR = 'N'. */ 00127 00128 /* RFP A RFP A */ 00129 00130 /* 03 04 05 33 43 53 */ 00131 /* 13 14 15 00 44 54 */ 00132 /* 23 24 25 10 11 55 */ 00133 /* 33 34 35 20 21 22 */ 00134 /* 00 44 45 30 31 32 */ 00135 /* 01 11 55 40 41 42 */ 00136 /* 02 12 22 50 51 52 */ 00137 00138 /* Now let TRANSR = 'T'. RFP A in both UPLO cases is just the */ 00139 /* transpose of RFP A above. One therefore gets: */ 00140 00141 00142 /* RFP A RFP A */ 00143 00144 /* 03 13 23 33 00 01 02 33 00 10 20 30 40 50 */ 00145 /* 04 14 24 34 44 11 12 43 44 11 21 31 41 51 */ 00146 /* 05 15 25 35 45 55 22 53 54 55 22 32 42 52 */ 00147 00148 00149 /* We first consider Rectangular Full Packed (RFP) Format when N is */ 00150 /* odd. We give an example where N = 5. */ 00151 00152 /* AP is Upper AP is Lower */ 00153 00154 /* 00 01 02 03 04 00 */ 00155 /* 11 12 13 14 10 11 */ 00156 /* 22 23 24 20 21 22 */ 00157 /* 33 34 30 31 32 33 */ 00158 /* 44 40 41 42 43 44 */ 00159 00160 00161 /* Let TRANSR = 'N'. RFP holds AP as follows: */ 00162 /* For UPLO = 'U' the upper trapezoid A(0:4,0:2) consists of the last */ 00163 /* three columns of AP upper. The lower triangle A(3:4,0:1) consists of */ 00164 /* the transpose of the first two columns of AP upper. */ 00165 /* For UPLO = 'L' the lower trapezoid A(0:4,0:2) consists of the first */ 00166 /* three columns of AP lower. The upper triangle A(0:1,1:2) consists of */ 00167 /* the transpose of the last two columns of AP lower. */ 00168 /* This covers the case N odd and TRANSR = 'N'. */ 00169 00170 /* RFP A RFP A */ 00171 00172 /* 02 03 04 00 33 43 */ 00173 /* 12 13 14 10 11 44 */ 00174 /* 22 23 24 20 21 22 */ 00175 /* 00 33 34 30 31 32 */ 00176 /* 01 11 44 40 41 42 */ 00177 00178 /* Now let TRANSR = 'T'. RFP A in both UPLO cases is just the */ 00179 /* transpose of RFP A above. One therefore gets: */ 00180 00181 /* RFP A RFP A */ 00182 00183 /* 02 12 22 00 01 00 10 20 30 40 50 */ 00184 /* 03 13 23 33 11 33 11 21 31 41 51 */ 00185 /* 04 14 24 34 44 43 44 22 32 42 52 */ 00186 00187 /* ===================================================================== */ 00188 00189 /* .. Parameters .. */ 00190 /* .. */ 00191 /* .. Local Scalars .. */ 00192 /* .. */ 00193 /* .. External Functions .. */ 00194 /* .. */ 00195 /* .. External Subroutines .. */ 00196 /* .. */ 00197 /* .. Intrinsic Functions .. */ 00198 /* .. */ 00199 /* .. Executable Statements .. */ 00200 00201 /* Test the input parameters. */ 00202 00203 *info = 0; 00204 normaltransr = lsame_(transr, "N"); 00205 lower = lsame_(uplo, "L"); 00206 if (! normaltransr && ! lsame_(transr, "T")) { 00207 *info = -1; 00208 } else if (! lower && ! lsame_(uplo, "U")) { 00209 *info = -2; 00210 } else if (! lsame_(diag, "N") && ! lsame_(diag, 00211 "U")) { 00212 *info = -3; 00213 } else if (*n < 0) { 00214 *info = -4; 00215 } 00216 if (*info != 0) { 00217 i__1 = -(*info); 00218 xerbla_("DTFTRI", &i__1); 00219 return 0; 00220 } 00221 00222 /* Quick return if possible */ 00223 00224 if (*n == 0) { 00225 return 0; 00226 } 00227 00228 /* If N is odd, set NISODD = .TRUE. */ 00229 /* If N is even, set K = N/2 and NISODD = .FALSE. */ 00230 00231 if (*n % 2 == 0) { 00232 k = *n / 2; 00233 nisodd = FALSE_; 00234 } else { 00235 nisodd = TRUE_; 00236 } 00237 00238 /* Set N1 and N2 depending on LOWER */ 00239 00240 if (lower) { 00241 n2 = *n / 2; 00242 n1 = *n - n2; 00243 } else { 00244 n1 = *n / 2; 00245 n2 = *n - n1; 00246 } 00247 00248 00249 /* start execution: there are eight cases */ 00250 00251 if (nisodd) { 00252 00253 /* N is odd */ 00254 00255 if (normaltransr) { 00256 00257 /* N is odd and TRANSR = 'N' */ 00258 00259 if (lower) { 00260 00261 /* SRPA for LOWER, NORMAL and N is odd ( a(0:n-1,0:n1-1) ) */ 00262 /* T1 -> a(0,0), T2 -> a(0,1), S -> a(n1,0) */ 00263 /* T1 -> a(0), T2 -> a(n), S -> a(n1) */ 00264 00265 dtrtri_("L", diag, &n1, a, n, info); 00266 if (*info > 0) { 00267 return 0; 00268 } 00269 dtrmm_("R", "L", "N", diag, &n2, &n1, &c_b13, a, n, &a[n1], n); 00270 dtrtri_("U", diag, &n2, &a[*n], n, info) 00271 ; 00272 if (*info > 0) { 00273 *info += n1; 00274 } 00275 if (*info > 0) { 00276 return 0; 00277 } 00278 dtrmm_("L", "U", "T", diag, &n2, &n1, &c_b18, &a[*n], n, &a[ 00279 n1], n); 00280 00281 } else { 00282 00283 /* SRPA for UPPER, NORMAL and N is odd ( a(0:n-1,0:n2-1) */ 00284 /* T1 -> a(n1+1,0), T2 -> a(n1,0), S -> a(0,0) */ 00285 /* T1 -> a(n2), T2 -> a(n1), S -> a(0) */ 00286 00287 dtrtri_("L", diag, &n1, &a[n2], n, info) 00288 ; 00289 if (*info > 0) { 00290 return 0; 00291 } 00292 dtrmm_("L", "L", "T", diag, &n1, &n2, &c_b13, &a[n2], n, a, n); 00293 dtrtri_("U", diag, &n2, &a[n1], n, info) 00294 ; 00295 if (*info > 0) { 00296 *info += n1; 00297 } 00298 if (*info > 0) { 00299 return 0; 00300 } 00301 dtrmm_("R", "U", "N", diag, &n1, &n2, &c_b18, &a[n1], n, a, n); 00302 00303 } 00304 00305 } else { 00306 00307 /* N is odd and TRANSR = 'T' */ 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 dtrtri_("U", diag, &n1, a, &n1, info); 00315 if (*info > 0) { 00316 return 0; 00317 } 00318 dtrmm_("L", "U", "N", diag, &n1, &n2, &c_b13, a, &n1, &a[n1 * 00319 n1], &n1); 00320 dtrtri_("L", diag, &n2, &a[1], &n1, info); 00321 if (*info > 0) { 00322 *info += n1; 00323 } 00324 if (*info > 0) { 00325 return 0; 00326 } 00327 dtrmm_("R", "L", "T", diag, &n1, &n2, &c_b18, &a[1], &n1, &a[ 00328 n1 * n1], &n1); 00329 00330 } else { 00331 00332 /* SRPA for UPPER, TRANSPOSE and N is odd */ 00333 /* T1 -> a(0+n2*n2), T2 -> a(0+n1*n2), S -> a(0) */ 00334 00335 dtrtri_("U", diag, &n1, &a[n2 * n2], &n2, info); 00336 if (*info > 0) { 00337 return 0; 00338 } 00339 dtrmm_("R", "U", "T", diag, &n2, &n1, &c_b13, &a[n2 * n2], & 00340 n2, a, &n2); 00341 dtrtri_("L", diag, &n2, &a[n1 * n2], &n2, info); 00342 if (*info > 0) { 00343 *info += n1; 00344 } 00345 if (*info > 0) { 00346 return 0; 00347 } 00348 dtrmm_("L", "L", "N", diag, &n2, &n1, &c_b18, &a[n1 * n2], & 00349 n2, a, &n2); 00350 } 00351 00352 } 00353 00354 } else { 00355 00356 /* N is even */ 00357 00358 if (normaltransr) { 00359 00360 /* N is even and TRANSR = 'N' */ 00361 00362 if (lower) { 00363 00364 /* SRPA for LOWER, NORMAL, and N is even ( a(0:n,0:k-1) ) */ 00365 /* T1 -> a(1,0), T2 -> a(0,0), S -> a(k+1,0) */ 00366 /* T1 -> a(1), T2 -> a(0), S -> a(k+1) */ 00367 00368 i__1 = *n + 1; 00369 dtrtri_("L", diag, &k, &a[1], &i__1, info); 00370 if (*info > 0) { 00371 return 0; 00372 } 00373 i__1 = *n + 1; 00374 i__2 = *n + 1; 00375 dtrmm_("R", "L", "N", diag, &k, &k, &c_b13, &a[1], &i__1, &a[ 00376 k + 1], &i__2); 00377 i__1 = *n + 1; 00378 dtrtri_("U", diag, &k, a, &i__1, info); 00379 if (*info > 0) { 00380 *info += k; 00381 } 00382 if (*info > 0) { 00383 return 0; 00384 } 00385 i__1 = *n + 1; 00386 i__2 = *n + 1; 00387 dtrmm_("L", "U", "T", diag, &k, &k, &c_b18, a, &i__1, &a[k + 00388 1], &i__2) 00389 ; 00390 00391 } else { 00392 00393 /* SRPA for UPPER, NORMAL, and N is even ( a(0:n,0:k-1) ) */ 00394 /* T1 -> a(k+1,0) , T2 -> a(k,0), S -> a(0,0) */ 00395 /* T1 -> a(k+1), T2 -> a(k), S -> a(0) */ 00396 00397 i__1 = *n + 1; 00398 dtrtri_("L", diag, &k, &a[k + 1], &i__1, info); 00399 if (*info > 0) { 00400 return 0; 00401 } 00402 i__1 = *n + 1; 00403 i__2 = *n + 1; 00404 dtrmm_("L", "L", "T", diag, &k, &k, &c_b13, &a[k + 1], &i__1, 00405 a, &i__2); 00406 i__1 = *n + 1; 00407 dtrtri_("U", diag, &k, &a[k], &i__1, info); 00408 if (*info > 0) { 00409 *info += k; 00410 } 00411 if (*info > 0) { 00412 return 0; 00413 } 00414 i__1 = *n + 1; 00415 i__2 = *n + 1; 00416 dtrmm_("R", "U", "N", diag, &k, &k, &c_b18, &a[k], &i__1, a, & 00417 i__2); 00418 } 00419 } else { 00420 00421 /* N is even and TRANSR = 'T' */ 00422 00423 if (lower) { 00424 00425 /* SRPA for LOWER, TRANSPOSE and N is even (see paper) */ 00426 /* T1 -> B(0,1), T2 -> B(0,0), S -> B(0,k+1) */ 00427 /* T1 -> a(0+k), T2 -> a(0+0), S -> a(0+k*(k+1)); lda=k */ 00428 00429 dtrtri_("U", diag, &k, &a[k], &k, info); 00430 if (*info > 0) { 00431 return 0; 00432 } 00433 dtrmm_("L", "U", "N", diag, &k, &k, &c_b13, &a[k], &k, &a[k * 00434 (k + 1)], &k); 00435 dtrtri_("L", diag, &k, a, &k, info); 00436 if (*info > 0) { 00437 *info += k; 00438 } 00439 if (*info > 0) { 00440 return 0; 00441 } 00442 dtrmm_("R", "L", "T", diag, &k, &k, &c_b18, a, &k, &a[k * (k 00443 + 1)], &k) 00444 ; 00445 } else { 00446 00447 /* SRPA for UPPER, TRANSPOSE and N is even (see paper) */ 00448 /* T1 -> B(0,k+1), T2 -> B(0,k), S -> B(0,0) */ 00449 /* T1 -> a(0+k*(k+1)), T2 -> a(0+k*k), S -> a(0+0)); lda=k */ 00450 00451 dtrtri_("U", diag, &k, &a[k * (k + 1)], &k, info); 00452 if (*info > 0) { 00453 return 0; 00454 } 00455 dtrmm_("R", "U", "T", diag, &k, &k, &c_b13, &a[k * (k + 1)], & 00456 k, a, &k); 00457 dtrtri_("L", diag, &k, &a[k * k], &k, info); 00458 if (*info > 0) { 00459 *info += k; 00460 } 00461 if (*info > 0) { 00462 return 0; 00463 } 00464 dtrmm_("L", "L", "N", diag, &k, &k, &c_b18, &a[k * k], &k, a, 00465 &k); 00466 } 00467 } 00468 } 00469 00470 return 0; 00471 00472 /* End of DTFTRI */ 00473 00474 } /* dtftri_ */