annotate ext/clapack/src/dgetri.c @ 211:a41bea655151 msvc

Rename FFT back again, now we have our own project
author Chris Cannam
date Mon, 05 Feb 2018 17:40:13 +0000
parents 45330e0d2819
children
rev   line source
Chris@202 1 /* dgetri.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_b20 = -1.;
Chris@202 22 static doublereal c_b22 = 1.;
Chris@202 23
Chris@202 24 /* Subroutine */ int dgetri_(integer *n, doublereal *a, integer *lda, integer
Chris@202 25 *ipiv, doublereal *work, integer *lwork, integer *info)
Chris@202 26 {
Chris@202 27 /* System generated locals */
Chris@202 28 integer a_dim1, a_offset, i__1, i__2, i__3;
Chris@202 29
Chris@202 30 /* Local variables */
Chris@202 31 integer i__, j, jb, nb, jj, jp, nn, iws;
Chris@202 32 extern /* Subroutine */ int dgemm_(char *, char *, integer *, integer *,
Chris@202 33 integer *, doublereal *, doublereal *, integer *, doublereal *,
Chris@202 34 integer *, doublereal *, doublereal *, integer *),
Chris@202 35 dgemv_(char *, integer *, integer *, doublereal *, doublereal *,
Chris@202 36 integer *, doublereal *, integer *, doublereal *, doublereal *,
Chris@202 37 integer *);
Chris@202 38 integer nbmin;
Chris@202 39 extern /* Subroutine */ int dswap_(integer *, doublereal *, integer *,
Chris@202 40 doublereal *, integer *), dtrsm_(char *, char *, char *, char *,
Chris@202 41 integer *, integer *, doublereal *, doublereal *, integer *,
Chris@202 42 doublereal *, integer *), xerbla_(
Chris@202 43 char *, integer *);
Chris@202 44 extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
Chris@202 45 integer *, integer *);
Chris@202 46 integer ldwork;
Chris@202 47 extern /* Subroutine */ int dtrtri_(char *, char *, integer *, doublereal
Chris@202 48 *, integer *, integer *);
Chris@202 49 integer lwkopt;
Chris@202 50 logical lquery;
Chris@202 51
Chris@202 52
Chris@202 53 /* -- LAPACK routine (version 3.2) -- */
Chris@202 54 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
Chris@202 55 /* November 2006 */
Chris@202 56
Chris@202 57 /* .. Scalar Arguments .. */
Chris@202 58 /* .. */
Chris@202 59 /* .. Array Arguments .. */
Chris@202 60 /* .. */
Chris@202 61
Chris@202 62 /* Purpose */
Chris@202 63 /* ======= */
Chris@202 64
Chris@202 65 /* DGETRI computes the inverse of a matrix using the LU factorization */
Chris@202 66 /* computed by DGETRF. */
Chris@202 67
Chris@202 68 /* This method inverts U and then computes inv(A) by solving the system */
Chris@202 69 /* inv(A)*L = inv(U) for inv(A). */
Chris@202 70
Chris@202 71 /* Arguments */
Chris@202 72 /* ========= */
Chris@202 73
Chris@202 74 /* N (input) INTEGER */
Chris@202 75 /* The order of the matrix A. N >= 0. */
Chris@202 76
Chris@202 77 /* A (input/output) DOUBLE PRECISION array, dimension (LDA,N) */
Chris@202 78 /* On entry, the factors L and U from the factorization */
Chris@202 79 /* A = P*L*U as computed by DGETRF. */
Chris@202 80 /* On exit, if INFO = 0, the inverse of the original matrix A. */
Chris@202 81
Chris@202 82 /* LDA (input) INTEGER */
Chris@202 83 /* The leading dimension of the array A. LDA >= max(1,N). */
Chris@202 84
Chris@202 85 /* IPIV (input) INTEGER array, dimension (N) */
Chris@202 86 /* The pivot indices from DGETRF; for 1<=i<=N, row i of the */
Chris@202 87 /* matrix was interchanged with row IPIV(i). */
Chris@202 88
Chris@202 89 /* WORK (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK)) */
Chris@202 90 /* On exit, if INFO=0, then WORK(1) returns the optimal LWORK. */
Chris@202 91
Chris@202 92 /* LWORK (input) INTEGER */
Chris@202 93 /* The dimension of the array WORK. LWORK >= max(1,N). */
Chris@202 94 /* For optimal performance LWORK >= N*NB, where NB is */
Chris@202 95 /* the optimal blocksize returned by ILAENV. */
Chris@202 96
Chris@202 97 /* If LWORK = -1, then a workspace query is assumed; the routine */
Chris@202 98 /* only calculates the optimal size of the WORK array, returns */
Chris@202 99 /* this value as the first entry of the WORK array, and no error */
Chris@202 100 /* message related to LWORK is issued by XERBLA. */
Chris@202 101
Chris@202 102 /* INFO (output) INTEGER */
Chris@202 103 /* = 0: successful exit */
Chris@202 104 /* < 0: if INFO = -i, the i-th argument had an illegal value */
Chris@202 105 /* > 0: if INFO = i, U(i,i) is exactly zero; the matrix is */
Chris@202 106 /* singular and its inverse could not be computed. */
Chris@202 107
Chris@202 108 /* ===================================================================== */
Chris@202 109
Chris@202 110 /* .. Parameters .. */
Chris@202 111 /* .. */
Chris@202 112 /* .. Local Scalars .. */
Chris@202 113 /* .. */
Chris@202 114 /* .. External Functions .. */
Chris@202 115 /* .. */
Chris@202 116 /* .. External Subroutines .. */
Chris@202 117 /* .. */
Chris@202 118 /* .. Intrinsic Functions .. */
Chris@202 119 /* .. */
Chris@202 120 /* .. Executable Statements .. */
Chris@202 121
Chris@202 122 /* Test the input parameters. */
Chris@202 123
Chris@202 124 /* Parameter adjustments */
Chris@202 125 a_dim1 = *lda;
Chris@202 126 a_offset = 1 + a_dim1;
Chris@202 127 a -= a_offset;
Chris@202 128 --ipiv;
Chris@202 129 --work;
Chris@202 130
Chris@202 131 /* Function Body */
Chris@202 132 *info = 0;
Chris@202 133 nb = ilaenv_(&c__1, "DGETRI", " ", n, &c_n1, &c_n1, &c_n1);
Chris@202 134 lwkopt = *n * nb;
Chris@202 135 work[1] = (doublereal) lwkopt;
Chris@202 136 lquery = *lwork == -1;
Chris@202 137 if (*n < 0) {
Chris@202 138 *info = -1;
Chris@202 139 } else if (*lda < max(1,*n)) {
Chris@202 140 *info = -3;
Chris@202 141 } else if (*lwork < max(1,*n) && ! lquery) {
Chris@202 142 *info = -6;
Chris@202 143 }
Chris@202 144 if (*info != 0) {
Chris@202 145 i__1 = -(*info);
Chris@202 146 xerbla_("DGETRI", &i__1);
Chris@202 147 return 0;
Chris@202 148 } else if (lquery) {
Chris@202 149 return 0;
Chris@202 150 }
Chris@202 151
Chris@202 152 /* Quick return if possible */
Chris@202 153
Chris@202 154 if (*n == 0) {
Chris@202 155 return 0;
Chris@202 156 }
Chris@202 157
Chris@202 158 /* Form inv(U). If INFO > 0 from DTRTRI, then U is singular, */
Chris@202 159 /* and the inverse is not computed. */
Chris@202 160
Chris@202 161 dtrtri_("Upper", "Non-unit", n, &a[a_offset], lda, info);
Chris@202 162 if (*info > 0) {
Chris@202 163 return 0;
Chris@202 164 }
Chris@202 165
Chris@202 166 nbmin = 2;
Chris@202 167 ldwork = *n;
Chris@202 168 if (nb > 1 && nb < *n) {
Chris@202 169 /* Computing MAX */
Chris@202 170 i__1 = ldwork * nb;
Chris@202 171 iws = max(i__1,1);
Chris@202 172 if (*lwork < iws) {
Chris@202 173 nb = *lwork / ldwork;
Chris@202 174 /* Computing MAX */
Chris@202 175 i__1 = 2, i__2 = ilaenv_(&c__2, "DGETRI", " ", n, &c_n1, &c_n1, &
Chris@202 176 c_n1);
Chris@202 177 nbmin = max(i__1,i__2);
Chris@202 178 }
Chris@202 179 } else {
Chris@202 180 iws = *n;
Chris@202 181 }
Chris@202 182
Chris@202 183 /* Solve the equation inv(A)*L = inv(U) for inv(A). */
Chris@202 184
Chris@202 185 if (nb < nbmin || nb >= *n) {
Chris@202 186
Chris@202 187 /* Use unblocked code. */
Chris@202 188
Chris@202 189 for (j = *n; j >= 1; --j) {
Chris@202 190
Chris@202 191 /* Copy current column of L to WORK and replace with zeros. */
Chris@202 192
Chris@202 193 i__1 = *n;
Chris@202 194 for (i__ = j + 1; i__ <= i__1; ++i__) {
Chris@202 195 work[i__] = a[i__ + j * a_dim1];
Chris@202 196 a[i__ + j * a_dim1] = 0.;
Chris@202 197 /* L10: */
Chris@202 198 }
Chris@202 199
Chris@202 200 /* Compute current column of inv(A). */
Chris@202 201
Chris@202 202 if (j < *n) {
Chris@202 203 i__1 = *n - j;
Chris@202 204 dgemv_("No transpose", n, &i__1, &c_b20, &a[(j + 1) * a_dim1
Chris@202 205 + 1], lda, &work[j + 1], &c__1, &c_b22, &a[j * a_dim1
Chris@202 206 + 1], &c__1);
Chris@202 207 }
Chris@202 208 /* L20: */
Chris@202 209 }
Chris@202 210 } else {
Chris@202 211
Chris@202 212 /* Use blocked code. */
Chris@202 213
Chris@202 214 nn = (*n - 1) / nb * nb + 1;
Chris@202 215 i__1 = -nb;
Chris@202 216 for (j = nn; i__1 < 0 ? j >= 1 : j <= 1; j += i__1) {
Chris@202 217 /* Computing MIN */
Chris@202 218 i__2 = nb, i__3 = *n - j + 1;
Chris@202 219 jb = min(i__2,i__3);
Chris@202 220
Chris@202 221 /* Copy current block column of L to WORK and replace with */
Chris@202 222 /* zeros. */
Chris@202 223
Chris@202 224 i__2 = j + jb - 1;
Chris@202 225 for (jj = j; jj <= i__2; ++jj) {
Chris@202 226 i__3 = *n;
Chris@202 227 for (i__ = jj + 1; i__ <= i__3; ++i__) {
Chris@202 228 work[i__ + (jj - j) * ldwork] = a[i__ + jj * a_dim1];
Chris@202 229 a[i__ + jj * a_dim1] = 0.;
Chris@202 230 /* L30: */
Chris@202 231 }
Chris@202 232 /* L40: */
Chris@202 233 }
Chris@202 234
Chris@202 235 /* Compute current block column of inv(A). */
Chris@202 236
Chris@202 237 if (j + jb <= *n) {
Chris@202 238 i__2 = *n - j - jb + 1;
Chris@202 239 dgemm_("No transpose", "No transpose", n, &jb, &i__2, &c_b20,
Chris@202 240 &a[(j + jb) * a_dim1 + 1], lda, &work[j + jb], &
Chris@202 241 ldwork, &c_b22, &a[j * a_dim1 + 1], lda);
Chris@202 242 }
Chris@202 243 dtrsm_("Right", "Lower", "No transpose", "Unit", n, &jb, &c_b22, &
Chris@202 244 work[j], &ldwork, &a[j * a_dim1 + 1], lda);
Chris@202 245 /* L50: */
Chris@202 246 }
Chris@202 247 }
Chris@202 248
Chris@202 249 /* Apply column interchanges. */
Chris@202 250
Chris@202 251 for (j = *n - 1; j >= 1; --j) {
Chris@202 252 jp = ipiv[j];
Chris@202 253 if (jp != j) {
Chris@202 254 dswap_(n, &a[j * a_dim1 + 1], &c__1, &a[jp * a_dim1 + 1], &c__1);
Chris@202 255 }
Chris@202 256 /* L60: */
Chris@202 257 }
Chris@202 258
Chris@202 259 work[1] = (doublereal) iws;
Chris@202 260 return 0;
Chris@202 261
Chris@202 262 /* End of DGETRI */
Chris@202 263
Chris@202 264 } /* dgetri_ */