annotate ext/clapack/src/dgetri.c @ 483:fdaa63607c15

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