Mercurial > hg > qm-dsp
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_ */ |