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


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:55:47