annotate ext/clapack/src/dtrtri.c @ 210:cf62f73766e9 msvc

Add a MSVC build project. This is hard to use, because it depends on a BLAS library
author Chris Cannam
date Mon, 05 Feb 2018 17:36:47 +0000
parents 45330e0d2819
children
rev   line source
Chris@202 1 /* dtrtri.f -- translated by f2c (version 20061008).
Chris@202 2 You must link the resulting object file with libf2c:
Chris@202 3 on Microsoft Windows system, link with libf2c.lib;
Chris@202 4 on Linux or Unix systems, link with .../path/to/libf2c.a -lm
Chris@202 5 or, if you install libf2c.a in a standard place, with -lf2c -lm
Chris@202 6 -- in that order, at the end of the command line, as in
Chris@202 7 cc *.o -lf2c -lm
Chris@202 8 Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
Chris@202 9
Chris@202 10 http://www.netlib.org/f2c/libf2c.zip
Chris@202 11 */
Chris@202 12
Chris@202 13 #include "f2c.h"
Chris@202 14 #include "blaswrap.h"
Chris@202 15
Chris@202 16 /* Table of constant values */
Chris@202 17
Chris@202 18 static integer c__1 = 1;
Chris@202 19 static integer c_n1 = -1;
Chris@202 20 static integer c__2 = 2;
Chris@202 21 static doublereal c_b18 = 1.;
Chris@202 22 static doublereal c_b22 = -1.;
Chris@202 23
Chris@202 24 /* Subroutine */ int dtrtri_(char *uplo, char *diag, integer *n, doublereal *
Chris@202 25 a, integer *lda, integer *info)
Chris@202 26 {
Chris@202 27 /* System generated locals */
Chris@202 28 address a__1[2];
Chris@202 29 integer a_dim1, a_offset, i__1, i__2[2], i__3, i__4, i__5;
Chris@202 30 char ch__1[2];
Chris@202 31
Chris@202 32 /* Builtin functions */
Chris@202 33 /* Subroutine */ int s_cat(char *, char **, integer *, integer *, ftnlen);
Chris@202 34
Chris@202 35 /* Local variables */
Chris@202 36 integer j, jb, nb, nn;
Chris@202 37 extern logical lsame_(char *, char *);
Chris@202 38 extern /* Subroutine */ int dtrmm_(char *, char *, char *, char *,
Chris@202 39 integer *, integer *, doublereal *, doublereal *, integer *,
Chris@202 40 doublereal *, integer *), dtrsm_(
Chris@202 41 char *, char *, char *, char *, integer *, integer *, doublereal *
Chris@202 42 , doublereal *, integer *, doublereal *, integer *);
Chris@202 43 logical upper;
Chris@202 44 extern /* Subroutine */ int dtrti2_(char *, char *, integer *, doublereal
Chris@202 45 *, integer *, integer *), xerbla_(char *, integer
Chris@202 46 *);
Chris@202 47 extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
Chris@202 48 integer *, integer *);
Chris@202 49 logical nounit;
Chris@202 50
Chris@202 51
Chris@202 52 /* -- LAPACK routine (version 3.2) -- */
Chris@202 53 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
Chris@202 54 /* November 2006 */
Chris@202 55
Chris@202 56 /* .. Scalar Arguments .. */
Chris@202 57 /* .. */
Chris@202 58 /* .. Array Arguments .. */
Chris@202 59 /* .. */
Chris@202 60
Chris@202 61 /* Purpose */
Chris@202 62 /* ======= */
Chris@202 63
Chris@202 64 /* DTRTRI computes the inverse of a real upper or lower triangular */
Chris@202 65 /* matrix A. */
Chris@202 66
Chris@202 67 /* This is the Level 3 BLAS version of the algorithm. */
Chris@202 68
Chris@202 69 /* Arguments */
Chris@202 70 /* ========= */
Chris@202 71
Chris@202 72 /* UPLO (input) CHARACTER*1 */
Chris@202 73 /* = 'U': A is upper triangular; */
Chris@202 74 /* = 'L': A is lower triangular. */
Chris@202 75
Chris@202 76 /* DIAG (input) CHARACTER*1 */
Chris@202 77 /* = 'N': A is non-unit triangular; */
Chris@202 78 /* = 'U': A is unit triangular. */
Chris@202 79
Chris@202 80 /* N (input) INTEGER */
Chris@202 81 /* The order of the matrix A. N >= 0. */
Chris@202 82
Chris@202 83 /* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) */
Chris@202 84 /* On entry, the triangular matrix A. If UPLO = 'U', the */
Chris@202 85 /* leading N-by-N upper triangular part of the array A contains */
Chris@202 86 /* the upper triangular matrix, and the strictly lower */
Chris@202 87 /* triangular part of A is not referenced. If UPLO = 'L', the */
Chris@202 88 /* leading N-by-N lower triangular part of the array A contains */
Chris@202 89 /* the lower triangular matrix, and the strictly upper */
Chris@202 90 /* triangular part of A is not referenced. If DIAG = 'U', the */
Chris@202 91 /* diagonal elements of A are also not referenced and are */
Chris@202 92 /* assumed to be 1. */
Chris@202 93 /* On exit, the (triangular) inverse of the original matrix, in */
Chris@202 94 /* the same storage format. */
Chris@202 95
Chris@202 96 /* LDA (input) INTEGER */
Chris@202 97 /* The leading dimension of the array A. LDA >= max(1,N). */
Chris@202 98
Chris@202 99 /* INFO (output) INTEGER */
Chris@202 100 /* = 0: successful exit */
Chris@202 101 /* < 0: if INFO = -i, the i-th argument had an illegal value */
Chris@202 102 /* > 0: if INFO = i, A(i,i) is exactly zero. The triangular */
Chris@202 103 /* matrix is singular and its inverse can not be computed. */
Chris@202 104
Chris@202 105 /* ===================================================================== */
Chris@202 106
Chris@202 107 /* .. Parameters .. */
Chris@202 108 /* .. */
Chris@202 109 /* .. Local Scalars .. */
Chris@202 110 /* .. */
Chris@202 111 /* .. External Functions .. */
Chris@202 112 /* .. */
Chris@202 113 /* .. External Subroutines .. */
Chris@202 114 /* .. */
Chris@202 115 /* .. Intrinsic Functions .. */
Chris@202 116 /* .. */
Chris@202 117 /* .. Executable Statements .. */
Chris@202 118
Chris@202 119 /* Test the input parameters. */
Chris@202 120
Chris@202 121 /* Parameter adjustments */
Chris@202 122 a_dim1 = *lda;
Chris@202 123 a_offset = 1 + a_dim1;
Chris@202 124 a -= a_offset;
Chris@202 125
Chris@202 126 /* Function Body */
Chris@202 127 *info = 0;
Chris@202 128 upper = lsame_(uplo, "U");
Chris@202 129 nounit = lsame_(diag, "N");
Chris@202 130 if (! upper && ! lsame_(uplo, "L")) {
Chris@202 131 *info = -1;
Chris@202 132 } else if (! nounit && ! lsame_(diag, "U")) {
Chris@202 133 *info = -2;
Chris@202 134 } else if (*n < 0) {
Chris@202 135 *info = -3;
Chris@202 136 } else if (*lda < max(1,*n)) {
Chris@202 137 *info = -5;
Chris@202 138 }
Chris@202 139 if (*info != 0) {
Chris@202 140 i__1 = -(*info);
Chris@202 141 xerbla_("DTRTRI", &i__1);
Chris@202 142 return 0;
Chris@202 143 }
Chris@202 144
Chris@202 145 /* Quick return if possible */
Chris@202 146
Chris@202 147 if (*n == 0) {
Chris@202 148 return 0;
Chris@202 149 }
Chris@202 150
Chris@202 151 /* Check for singularity if non-unit. */
Chris@202 152
Chris@202 153 if (nounit) {
Chris@202 154 i__1 = *n;
Chris@202 155 for (*info = 1; *info <= i__1; ++(*info)) {
Chris@202 156 if (a[*info + *info * a_dim1] == 0.) {
Chris@202 157 return 0;
Chris@202 158 }
Chris@202 159 /* L10: */
Chris@202 160 }
Chris@202 161 *info = 0;
Chris@202 162 }
Chris@202 163
Chris@202 164 /* Determine the block size for this environment. */
Chris@202 165
Chris@202 166 /* Writing concatenation */
Chris@202 167 i__2[0] = 1, a__1[0] = uplo;
Chris@202 168 i__2[1] = 1, a__1[1] = diag;
Chris@202 169 s_cat(ch__1, a__1, i__2, &c__2, (ftnlen)2);
Chris@202 170 nb = ilaenv_(&c__1, "DTRTRI", ch__1, n, &c_n1, &c_n1, &c_n1);
Chris@202 171 if (nb <= 1 || nb >= *n) {
Chris@202 172
Chris@202 173 /* Use unblocked code */
Chris@202 174
Chris@202 175 dtrti2_(uplo, diag, n, &a[a_offset], lda, info);
Chris@202 176 } else {
Chris@202 177
Chris@202 178 /* Use blocked code */
Chris@202 179
Chris@202 180 if (upper) {
Chris@202 181
Chris@202 182 /* Compute inverse of upper triangular matrix */
Chris@202 183
Chris@202 184 i__1 = *n;
Chris@202 185 i__3 = nb;
Chris@202 186 for (j = 1; i__3 < 0 ? j >= i__1 : j <= i__1; j += i__3) {
Chris@202 187 /* Computing MIN */
Chris@202 188 i__4 = nb, i__5 = *n - j + 1;
Chris@202 189 jb = min(i__4,i__5);
Chris@202 190
Chris@202 191 /* Compute rows 1:j-1 of current block column */
Chris@202 192
Chris@202 193 i__4 = j - 1;
Chris@202 194 dtrmm_("Left", "Upper", "No transpose", diag, &i__4, &jb, &
Chris@202 195 c_b18, &a[a_offset], lda, &a[j * a_dim1 + 1], lda);
Chris@202 196 i__4 = j - 1;
Chris@202 197 dtrsm_("Right", "Upper", "No transpose", diag, &i__4, &jb, &
Chris@202 198 c_b22, &a[j + j * a_dim1], lda, &a[j * a_dim1 + 1],
Chris@202 199 lda);
Chris@202 200
Chris@202 201 /* Compute inverse of current diagonal block */
Chris@202 202
Chris@202 203 dtrti2_("Upper", diag, &jb, &a[j + j * a_dim1], lda, info);
Chris@202 204 /* L20: */
Chris@202 205 }
Chris@202 206 } else {
Chris@202 207
Chris@202 208 /* Compute inverse of lower triangular matrix */
Chris@202 209
Chris@202 210 nn = (*n - 1) / nb * nb + 1;
Chris@202 211 i__3 = -nb;
Chris@202 212 for (j = nn; i__3 < 0 ? j >= 1 : j <= 1; j += i__3) {
Chris@202 213 /* Computing MIN */
Chris@202 214 i__1 = nb, i__4 = *n - j + 1;
Chris@202 215 jb = min(i__1,i__4);
Chris@202 216 if (j + jb <= *n) {
Chris@202 217
Chris@202 218 /* Compute rows j+jb:n of current block column */
Chris@202 219
Chris@202 220 i__1 = *n - j - jb + 1;
Chris@202 221 dtrmm_("Left", "Lower", "No transpose", diag, &i__1, &jb,
Chris@202 222 &c_b18, &a[j + jb + (j + jb) * a_dim1], lda, &a[j
Chris@202 223 + jb + j * a_dim1], lda);
Chris@202 224 i__1 = *n - j - jb + 1;
Chris@202 225 dtrsm_("Right", "Lower", "No transpose", diag, &i__1, &jb,
Chris@202 226 &c_b22, &a[j + j * a_dim1], lda, &a[j + jb + j *
Chris@202 227 a_dim1], lda);
Chris@202 228 }
Chris@202 229
Chris@202 230 /* Compute inverse of current diagonal block */
Chris@202 231
Chris@202 232 dtrti2_("Lower", diag, &jb, &a[j + j * a_dim1], lda, info);
Chris@202 233 /* L30: */
Chris@202 234 }
Chris@202 235 }
Chris@202 236 }
Chris@202 237
Chris@202 238 return 0;
Chris@202 239
Chris@202 240 /* End of DTRTRI */
Chris@202 241
Chris@202 242 } /* dtrtri_ */