comparison ext/clapack/src/dgetri.c @ 430:335af74a25b6

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