1 /* lapack/double/dgecon.f -- translated by f2c (version 20050501).
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 #ifdef __cplusplus
14 extern "C" {
15 #endif
16 #include "v3p_netlib.h"
17
18 /* Table of constant values */
19
20 static integer c__1 = 1;
21
22 /*< >*/
dgecon_(char * norm,integer * n,doublereal * a,integer * lda,doublereal * anorm,doublereal * rcond,doublereal * work,integer * iwork,integer * info,ftnlen norm_len)23 /* Subroutine */ int dgecon_(char *norm, integer *n, doublereal *a, integer *
24 lda, doublereal *anorm, doublereal *rcond, doublereal *work, integer *
25 iwork, integer *info, ftnlen norm_len)
26 {
27 /* System generated locals */
28 integer a_dim1, a_offset, i__1;
29 doublereal d__1;
30
31 /* Local variables */
32 doublereal sl;
33 integer ix;
34 doublereal su;
35 integer kase, kase1;
36 doublereal scale;
37 extern logical lsame_(const char *, const char *, ftnlen, ftnlen);
38 extern /* Subroutine */ int drscl_(integer *, doublereal *, doublereal *,
39 integer *);
40 extern doublereal dlamch_(char *, ftnlen);
41 extern /* Subroutine */ int dlacon_(integer *, doublereal *, doublereal *,
42 integer *, doublereal *, integer *);
43 extern integer idamax_(integer *, doublereal *, integer *);
44 extern /* Subroutine */ int xerbla_(char *, integer *, ftnlen);
45 doublereal ainvnm;
46 extern /* Subroutine */ int dlatrs_(char *, char *, char *, char *,
47 integer *, doublereal *, integer *, doublereal *, doublereal *,
48 doublereal *, integer *, ftnlen, ftnlen, ftnlen, ftnlen);
49 logical onenrm;
50 char normin[1];
51 doublereal smlnum;
52 (void)norm_len;
53
54 /* -- LAPACK routine (version 3.0) -- */
55 /* Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., */
56 /* Courant Institute, Argonne National Lab, and Rice University */
57 /* February 29, 1992 */
58
59 /* .. Scalar Arguments .. */
60 /*< CHARACTER NORM >*/
61 /*< INTEGER INFO, LDA, N >*/
62 /*< DOUBLE PRECISION ANORM, RCOND >*/
63 /* .. */
64 /* .. Array Arguments .. */
65 /*< INTEGER IWORK( * ) >*/
66 /*< DOUBLE PRECISION A( LDA, * ), WORK( * ) >*/
67 /* .. */
68
69 /* Purpose */
70 /* ======= */
71
72 /* DGECON estimates the reciprocal of the condition number of a general */
73 /* real matrix A, in either the 1-norm or the infinity-norm, using */
74 /* the LU factorization computed by DGETRF. */
75
76 /* An estimate is obtained for norm(inv(A)), and the reciprocal of the */
77 /* condition number is computed as */
78 /* RCOND = 1 / ( norm(A) * norm(inv(A)) ). */
79
80 /* Arguments */
81 /* ========= */
82
83 /* NORM (input) CHARACTER*1 */
84 /* Specifies whether the 1-norm condition number or the */
85 /* infinity-norm condition number is required: */
86 /* = '1' or 'O': 1-norm; */
87 /* = 'I': Infinity-norm. */
88
89 /* N (input) INTEGER */
90 /* The order of the matrix A. N >= 0. */
91
92 /* A (input) DOUBLE PRECISION array, dimension (LDA,N) */
93 /* The factors L and U from the factorization A = P*L*U */
94 /* as computed by DGETRF. */
95
96 /* LDA (input) INTEGER */
97 /* The leading dimension of the array A. LDA >= max(1,N). */
98
99 /* ANORM (input) DOUBLE PRECISION */
100 /* If NORM = '1' or 'O', the 1-norm of the original matrix A. */
101 /* If NORM = 'I', the infinity-norm of the original matrix A. */
102
103 /* RCOND (output) DOUBLE PRECISION */
104 /* The reciprocal of the condition number of the matrix A, */
105 /* computed as RCOND = 1/(norm(A) * norm(inv(A))). */
106
107 /* WORK (workspace) DOUBLE PRECISION array, dimension (4*N) */
108
109 /* IWORK (workspace) INTEGER array, dimension (N) */
110
111 /* INFO (output) INTEGER */
112 /* = 0: successful exit */
113 /* < 0: if INFO = -i, the i-th argument had an illegal value */
114
115 /* ===================================================================== */
116
117 /* .. Parameters .. */
118 /*< DOUBLE PRECISION ONE, ZERO >*/
119 /*< PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) >*/
120 /* .. */
121 /* .. Local Scalars .. */
122 /*< LOGICAL ONENRM >*/
123 /*< CHARACTER NORMIN >*/
124 /*< INTEGER IX, KASE, KASE1 >*/
125 /*< DOUBLE PRECISION AINVNM, SCALE, SL, SMLNUM, SU >*/
126 /* .. */
127 /* .. External Functions .. */
128 /*< LOGICAL LSAME >*/
129 /*< INTEGER IDAMAX >*/
130 /*< DOUBLE PRECISION DLAMCH >*/
131 /*< EXTERNAL LSAME, IDAMAX, DLAMCH >*/
132 /* .. */
133 /* .. External Subroutines .. */
134 /*< EXTERNAL DLACON, DLATRS, DRSCL, XERBLA >*/
135 /* .. */
136 /* .. Intrinsic Functions .. */
137 /*< INTRINSIC ABS, MAX >*/
138 /* .. */
139 /* .. Executable Statements .. */
140
141 /* Test the input parameters. */
142
143 /*< INFO = 0 >*/
144 /* Parameter adjustments */
145 a_dim1 = *lda;
146 a_offset = 1 + a_dim1;
147 a -= a_offset;
148 --work;
149 --iwork;
150
151 /* Function Body */
152 *info = 0;
153 /*< ONENRM = NORM.EQ.'1' .OR. LSAME( NORM, 'O' ) >*/
154 onenrm = *(unsigned char *)norm == '1' || lsame_(norm, "O", (ftnlen)1, (
155 ftnlen)1);
156 /*< IF( .NOT.ONENRM .AND. .NOT.LSAME( NORM, 'I' ) ) THEN >*/
157 if (! onenrm && ! lsame_(norm, "I", (ftnlen)1, (ftnlen)1)) {
158 /*< INFO = -1 >*/
159 *info = -1;
160 /*< ELSE IF( N.LT.0 ) THEN >*/
161 } else if (*n < 0) {
162 /*< INFO = -2 >*/
163 *info = -2;
164 /*< ELSE IF( LDA.LT.MAX( 1, N ) ) THEN >*/
165 } else if (*lda < max(1,*n)) {
166 /*< INFO = -4 >*/
167 *info = -4;
168 /*< ELSE IF( ANORM.LT.ZERO ) THEN >*/
169 } else if (*anorm < 0.) {
170 /*< INFO = -5 >*/
171 *info = -5;
172 /*< END IF >*/
173 }
174 /*< IF( INFO.NE.0 ) THEN >*/
175 if (*info != 0) {
176 /*< CALL XERBLA( 'DGECON', -INFO ) >*/
177 i__1 = -(*info);
178 xerbla_("DGECON", &i__1, (ftnlen)6);
179 /*< RETURN >*/
180 return 0;
181 /*< END IF >*/
182 }
183
184 /* Quick return if possible */
185
186 /*< RCOND = ZERO >*/
187 *rcond = 0.;
188 /*< IF( N.EQ.0 ) THEN >*/
189 if (*n == 0) {
190 /*< RCOND = ONE >*/
191 *rcond = 1.;
192 /*< RETURN >*/
193 return 0;
194 /*< ELSE IF( ANORM.EQ.ZERO ) THEN >*/
195 } else if (*anorm == 0.) {
196 /*< RETURN >*/
197 return 0;
198 /*< END IF >*/
199 }
200
201 /*< SMLNUM = DLAMCH( 'Safe minimum' ) >*/
202 smlnum = dlamch_("Safe minimum", (ftnlen)12);
203
204 /* Estimate the norm of inv(A). */
205
206 /*< AINVNM = ZERO >*/
207 ainvnm = 0.;
208 /*< NORMIN = 'N' >*/
209 *(unsigned char *)normin = 'N';
210 /*< IF( ONENRM ) THEN >*/
211 if (onenrm) {
212 /*< KASE1 = 1 >*/
213 kase1 = 1;
214 /*< ELSE >*/
215 } else {
216 /*< KASE1 = 2 >*/
217 kase1 = 2;
218 /*< END IF >*/
219 }
220 /*< KASE = 0 >*/
221 kase = 0;
222 /*< 10 CONTINUE >*/
223 L10:
224 /*< CALL DLACON( N, WORK( N+1 ), WORK, IWORK, AINVNM, KASE ) >*/
225 dlacon_(n, &work[*n + 1], &work[1], &iwork[1], &ainvnm, &kase);
226 /*< IF( KASE.NE.0 ) THEN >*/
227 if (kase != 0) {
228 /*< IF( KASE.EQ.KASE1 ) THEN >*/
229 if (kase == kase1) {
230
231 /* Multiply by inv(L). */
232
233 /*< >*/
234 dlatrs_("Lower", "No transpose", "Unit", normin, n, &a[a_offset],
235 lda, &work[1], &sl, &work[(*n << 1) + 1], info, (ftnlen)5,
236 (ftnlen)12, (ftnlen)4, (ftnlen)1);
237
238 /* Multiply by inv(U). */
239
240 /*< >*/
241 dlatrs_("Upper", "No transpose", "Non-unit", normin, n, &a[
242 a_offset], lda, &work[1], &su, &work[*n * 3 + 1], info, (
243 ftnlen)5, (ftnlen)12, (ftnlen)8, (ftnlen)1);
244 /*< ELSE >*/
245 } else {
246
247 /* Multiply by inv(U'). */
248
249 /*< >*/
250 dlatrs_("Upper", "Transpose", "Non-unit", normin, n, &a[a_offset],
251 lda, &work[1], &su, &work[*n * 3 + 1], info, (ftnlen)5, (
252 ftnlen)9, (ftnlen)8, (ftnlen)1);
253
254 /* Multiply by inv(L'). */
255
256 /*< >*/
257 dlatrs_("Lower", "Transpose", "Unit", normin, n, &a[a_offset],
258 lda, &work[1], &sl, &work[(*n << 1) + 1], info, (ftnlen)5,
259 (ftnlen)9, (ftnlen)4, (ftnlen)1);
260 /*< END IF >*/
261 }
262
263 /* Divide X by 1/(SL*SU) if doing so will not cause overflow. */
264
265 /*< SCALE = SL*SU >*/
266 scale = sl * su;
267 /*< NORMIN = 'Y' >*/
268 *(unsigned char *)normin = 'Y';
269 /*< IF( SCALE.NE.ONE ) THEN >*/
270 if (scale != 1.) {
271 /*< IX = IDAMAX( N, WORK, 1 ) >*/
272 ix = idamax_(n, &work[1], &c__1);
273 /*< >*/
274 if (scale < (d__1 = work[ix], abs(d__1)) * smlnum || scale == 0.)
275 {
276 goto L20;
277 }
278 /*< CALL DRSCL( N, SCALE, WORK, 1 ) >*/
279 drscl_(n, &scale, &work[1], &c__1);
280 /*< END IF >*/
281 }
282 /*< GO TO 10 >*/
283 goto L10;
284 /*< END IF >*/
285 }
286
287 /* Compute the estimate of the reciprocal condition number. */
288
289 /*< >*/
290 if (ainvnm != 0.) {
291 *rcond = 1. / ainvnm / *anorm;
292 }
293
294 /*< 20 CONTINUE >*/
295 L20:
296 /*< RETURN >*/
297 return 0;
298
299 /* End of DGECON */
300
301 /*< END >*/
302 } /* dgecon_ */
303
304 #ifdef __cplusplus
305 }
306 #endif
307