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