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