00001 /* sgeequb.f -- translated by f2c (version 20061008). 00002 You must link the resulting object file with libf2c: 00003 on Microsoft Windows system, link with libf2c.lib; 00004 on Linux or Unix systems, link with .../path/to/libf2c.a -lm 00005 or, if you install libf2c.a in a standard place, with -lf2c -lm 00006 -- in that order, at the end of the command line, as in 00007 cc *.o -lf2c -lm 00008 Source for libf2c is in /netlib/f2c/libf2c.zip, e.g., 00009 00010 http://www.netlib.org/f2c/libf2c.zip 00011 */ 00012 00013 #include "f2c.h" 00014 #include "blaswrap.h" 00015 00016 /* Subroutine */ int sgeequb_(integer *m, integer *n, real *a, integer *lda, 00017 real *r__, real *c__, real *rowcnd, real *colcnd, real *amax, integer 00018 *info) 00019 { 00020 /* System generated locals */ 00021 integer a_dim1, a_offset, i__1, i__2; 00022 real r__1, r__2, r__3; 00023 00024 /* Builtin functions */ 00025 double log(doublereal), pow_ri(real *, integer *); 00026 00027 /* Local variables */ 00028 integer i__, j; 00029 real radix, rcmin, rcmax; 00030 extern doublereal slamch_(char *); 00031 extern /* Subroutine */ int xerbla_(char *, integer *); 00032 real bignum, logrdx, smlnum; 00033 00034 00035 /* -- LAPACK routine (version 3.2) -- */ 00036 /* -- Contributed by James Demmel, Deaglan Halligan, Yozo Hida and -- */ 00037 /* -- Jason Riedy of Univ. of California Berkeley. -- */ 00038 /* -- November 2008 -- */ 00039 00040 /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */ 00041 /* -- Univ. of California Berkeley and NAG Ltd. -- */ 00042 00043 /* .. */ 00044 /* .. Scalar Arguments .. */ 00045 /* .. */ 00046 /* .. Array Arguments .. */ 00047 /* .. */ 00048 00049 /* Purpose */ 00050 /* ======= */ 00051 00052 /* SGEEQUB computes row and column scalings intended to equilibrate an */ 00053 /* M-by-N matrix A and reduce its condition number. R returns the row */ 00054 /* scale factors and C the column scale factors, chosen to try to make */ 00055 /* the largest element in each row and column of the matrix B with */ 00056 /* elements B(i,j)=R(i)*A(i,j)*C(j) have an absolute value of at most */ 00057 /* the radix. */ 00058 00059 /* R(i) and C(j) are restricted to be a power of the radix between */ 00060 /* SMLNUM = smallest safe number and BIGNUM = largest safe number. Use */ 00061 /* of these scaling factors is not guaranteed to reduce the condition */ 00062 /* number of A but works well in practice. */ 00063 00064 /* This routine differs from SGEEQU by restricting the scaling factors */ 00065 /* to a power of the radix. Baring over- and underflow, scaling by */ 00066 /* these factors introduces no additional rounding errors. However, the */ 00067 /* scaled entries' magnitured are no longer approximately 1 but lie */ 00068 /* between sqrt(radix) and 1/sqrt(radix). */ 00069 00070 /* Arguments */ 00071 /* ========= */ 00072 00073 /* M (input) INTEGER */ 00074 /* The number of rows of the matrix A. M >= 0. */ 00075 00076 /* N (input) INTEGER */ 00077 /* The number of columns of the matrix A. N >= 0. */ 00078 00079 /* A (input) REAL array, dimension (LDA,N) */ 00080 /* The M-by-N matrix whose equilibration factors are */ 00081 /* to be computed. */ 00082 00083 /* LDA (input) INTEGER */ 00084 /* The leading dimension of the array A. LDA >= max(1,M). */ 00085 00086 /* R (output) REAL array, dimension (M) */ 00087 /* If INFO = 0 or INFO > M, R contains the row scale factors */ 00088 /* for A. */ 00089 00090 /* C (output) REAL array, dimension (N) */ 00091 /* If INFO = 0, C contains the column scale factors for A. */ 00092 00093 /* ROWCND (output) REAL */ 00094 /* If INFO = 0 or INFO > M, ROWCND contains the ratio of the */ 00095 /* smallest R(i) to the largest R(i). If ROWCND >= 0.1 and */ 00096 /* AMAX is neither too large nor too small, it is not worth */ 00097 /* scaling by R. */ 00098 00099 /* COLCND (output) REAL */ 00100 /* If INFO = 0, COLCND contains the ratio of the smallest */ 00101 /* C(i) to the largest C(i). If COLCND >= 0.1, it is not */ 00102 /* worth scaling by C. */ 00103 00104 /* AMAX (output) REAL */ 00105 /* Absolute value of largest matrix element. If AMAX is very */ 00106 /* close to overflow or very close to underflow, the matrix */ 00107 /* should be scaled. */ 00108 00109 /* INFO (output) INTEGER */ 00110 /* = 0: successful exit */ 00111 /* < 0: if INFO = -i, the i-th argument had an illegal value */ 00112 /* > 0: if INFO = i, and i is */ 00113 /* <= M: the i-th row of A is exactly zero */ 00114 /* > M: the (i-M)-th column of A is exactly zero */ 00115 00116 /* ===================================================================== */ 00117 00118 /* .. Parameters .. */ 00119 /* .. */ 00120 /* .. Local Scalars .. */ 00121 /* .. */ 00122 /* .. External Functions .. */ 00123 /* .. */ 00124 /* .. External Subroutines .. */ 00125 /* .. */ 00126 /* .. Intrinsic Functions .. */ 00127 /* .. */ 00128 /* .. Executable Statements .. */ 00129 00130 /* Test the input parameters. */ 00131 00132 /* Parameter adjustments */ 00133 a_dim1 = *lda; 00134 a_offset = 1 + a_dim1; 00135 a -= a_offset; 00136 --r__; 00137 --c__; 00138 00139 /* Function Body */ 00140 *info = 0; 00141 if (*m < 0) { 00142 *info = -1; 00143 } else if (*n < 0) { 00144 *info = -2; 00145 } else if (*lda < max(1,*m)) { 00146 *info = -4; 00147 } 00148 if (*info != 0) { 00149 i__1 = -(*info); 00150 xerbla_("SGEEQUB", &i__1); 00151 return 0; 00152 } 00153 00154 /* Quick return if possible. */ 00155 00156 if (*m == 0 || *n == 0) { 00157 *rowcnd = 1.f; 00158 *colcnd = 1.f; 00159 *amax = 0.f; 00160 return 0; 00161 } 00162 00163 /* Get machine constants. Assume SMLNUM is a power of the radix. */ 00164 00165 smlnum = slamch_("S"); 00166 bignum = 1.f / smlnum; 00167 radix = slamch_("B"); 00168 logrdx = log(radix); 00169 00170 /* Compute row scale factors. */ 00171 00172 i__1 = *m; 00173 for (i__ = 1; i__ <= i__1; ++i__) { 00174 r__[i__] = 0.f; 00175 /* L10: */ 00176 } 00177 00178 /* Find the maximum element in each row. */ 00179 00180 i__1 = *n; 00181 for (j = 1; j <= i__1; ++j) { 00182 i__2 = *m; 00183 for (i__ = 1; i__ <= i__2; ++i__) { 00184 /* Computing MAX */ 00185 r__2 = r__[i__], r__3 = (r__1 = a[i__ + j * a_dim1], dabs(r__1)); 00186 r__[i__] = dmax(r__2,r__3); 00187 /* L20: */ 00188 } 00189 /* L30: */ 00190 } 00191 i__1 = *m; 00192 for (i__ = 1; i__ <= i__1; ++i__) { 00193 if (r__[i__] > 0.f) { 00194 i__2 = (integer) (log(r__[i__]) / logrdx); 00195 r__[i__] = pow_ri(&radix, &i__2); 00196 } 00197 } 00198 00199 /* Find the maximum and minimum scale factors. */ 00200 00201 rcmin = bignum; 00202 rcmax = 0.f; 00203 i__1 = *m; 00204 for (i__ = 1; i__ <= i__1; ++i__) { 00205 /* Computing MAX */ 00206 r__1 = rcmax, r__2 = r__[i__]; 00207 rcmax = dmax(r__1,r__2); 00208 /* Computing MIN */ 00209 r__1 = rcmin, r__2 = r__[i__]; 00210 rcmin = dmin(r__1,r__2); 00211 /* L40: */ 00212 } 00213 *amax = rcmax; 00214 00215 if (rcmin == 0.f) { 00216 00217 /* Find the first zero scale factor and return an error code. */ 00218 00219 i__1 = *m; 00220 for (i__ = 1; i__ <= i__1; ++i__) { 00221 if (r__[i__] == 0.f) { 00222 *info = i__; 00223 return 0; 00224 } 00225 /* L50: */ 00226 } 00227 } else { 00228 00229 /* Invert the scale factors. */ 00230 00231 i__1 = *m; 00232 for (i__ = 1; i__ <= i__1; ++i__) { 00233 /* Computing MIN */ 00234 /* Computing MAX */ 00235 r__2 = r__[i__]; 00236 r__1 = dmax(r__2,smlnum); 00237 r__[i__] = 1.f / dmin(r__1,bignum); 00238 /* L60: */ 00239 } 00240 00241 /* Compute ROWCND = min(R(I)) / max(R(I)). */ 00242 00243 *rowcnd = dmax(rcmin,smlnum) / dmin(rcmax,bignum); 00244 } 00245 00246 /* Compute column scale factors */ 00247 00248 i__1 = *n; 00249 for (j = 1; j <= i__1; ++j) { 00250 c__[j] = 0.f; 00251 /* L70: */ 00252 } 00253 00254 /* Find the maximum element in each column, */ 00255 /* assuming the row scaling computed above. */ 00256 00257 i__1 = *n; 00258 for (j = 1; j <= i__1; ++j) { 00259 i__2 = *m; 00260 for (i__ = 1; i__ <= i__2; ++i__) { 00261 /* Computing MAX */ 00262 r__2 = c__[j], r__3 = (r__1 = a[i__ + j * a_dim1], dabs(r__1)) * 00263 r__[i__]; 00264 c__[j] = dmax(r__2,r__3); 00265 /* L80: */ 00266 } 00267 if (c__[j] > 0.f) { 00268 i__2 = (integer) (log(c__[j]) / logrdx); 00269 c__[j] = pow_ri(&radix, &i__2); 00270 } 00271 /* L90: */ 00272 } 00273 00274 /* Find the maximum and minimum scale factors. */ 00275 00276 rcmin = bignum; 00277 rcmax = 0.f; 00278 i__1 = *n; 00279 for (j = 1; j <= i__1; ++j) { 00280 /* Computing MIN */ 00281 r__1 = rcmin, r__2 = c__[j]; 00282 rcmin = dmin(r__1,r__2); 00283 /* Computing MAX */ 00284 r__1 = rcmax, r__2 = c__[j]; 00285 rcmax = dmax(r__1,r__2); 00286 /* L100: */ 00287 } 00288 00289 if (rcmin == 0.f) { 00290 00291 /* Find the first zero scale factor and return an error code. */ 00292 00293 i__1 = *n; 00294 for (j = 1; j <= i__1; ++j) { 00295 if (c__[j] == 0.f) { 00296 *info = *m + j; 00297 return 0; 00298 } 00299 /* L110: */ 00300 } 00301 } else { 00302 00303 /* Invert the scale factors. */ 00304 00305 i__1 = *n; 00306 for (j = 1; j <= i__1; ++j) { 00307 /* Computing MIN */ 00308 /* Computing MAX */ 00309 r__2 = c__[j]; 00310 r__1 = dmax(r__2,smlnum); 00311 c__[j] = 1.f / dmin(r__1,bignum); 00312 /* L120: */ 00313 } 00314 00315 /* Compute COLCND = min(C(J)) / max(C(J)). */ 00316 00317 *colcnd = dmax(rcmin,smlnum) / dmin(rcmax,bignum); 00318 } 00319 00320 return 0; 00321 00322 /* End of SGEEQUB */ 00323 00324 } /* sgeequb_ */