00001 /* spoequb.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 spoequb_(integer *n, real *a, integer *lda, real *s, 00017 real *scond, real *amax, integer *info) 00018 { 00019 /* System generated locals */ 00020 integer a_dim1, a_offset, i__1, i__2; 00021 real r__1, r__2; 00022 00023 /* Builtin functions */ 00024 double log(doublereal), pow_ri(real *, integer *), sqrt(doublereal); 00025 00026 /* Local variables */ 00027 integer i__; 00028 real tmp, base, smin; 00029 extern doublereal slamch_(char *); 00030 extern /* Subroutine */ int xerbla_(char *, integer *); 00031 00032 00033 /* -- LAPACK routine (version 3.2) -- */ 00034 /* -- Contributed by James Demmel, Deaglan Halligan, Yozo Hida and -- */ 00035 /* -- Jason Riedy of Univ. of California Berkeley. -- */ 00036 /* -- November 2008 -- */ 00037 00038 /* -- LAPACK is a software package provided by Univ. of Tennessee, -- */ 00039 /* -- Univ. of California Berkeley and NAG Ltd. -- */ 00040 00041 /* .. */ 00042 /* .. Scalar Arguments .. */ 00043 /* .. */ 00044 /* .. Array Arguments .. */ 00045 /* .. */ 00046 00047 /* Purpose */ 00048 /* ======= */ 00049 00050 /* SPOEQU computes row and column scalings intended to equilibrate a */ 00051 /* symmetric positive definite matrix A and reduce its condition number */ 00052 /* (with respect to the two-norm). S contains the scale factors, */ 00053 /* S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with */ 00054 /* elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal. This */ 00055 /* choice of S puts the condition number of B within a factor N of the */ 00056 /* smallest possible condition number over all possible diagonal */ 00057 /* scalings. */ 00058 00059 /* Arguments */ 00060 /* ========= */ 00061 00062 /* N (input) INTEGER */ 00063 /* The order of the matrix A. N >= 0. */ 00064 00065 /* A (input) REAL array, dimension (LDA,N) */ 00066 /* The N-by-N symmetric positive definite matrix whose scaling */ 00067 /* factors are to be computed. Only the diagonal elements of A */ 00068 /* are referenced. */ 00069 00070 /* LDA (input) INTEGER */ 00071 /* The leading dimension of the array A. LDA >= max(1,N). */ 00072 00073 /* S (output) REAL array, dimension (N) */ 00074 /* If INFO = 0, S contains the scale factors for A. */ 00075 00076 /* SCOND (output) REAL */ 00077 /* If INFO = 0, S contains the ratio of the smallest S(i) to */ 00078 /* the largest S(i). If SCOND >= 0.1 and AMAX is neither too */ 00079 /* large nor too small, it is not worth scaling by S. */ 00080 00081 /* AMAX (output) REAL */ 00082 /* Absolute value of largest matrix element. If AMAX is very */ 00083 /* close to overflow or very close to underflow, the matrix */ 00084 /* should be scaled. */ 00085 00086 /* INFO (output) INTEGER */ 00087 /* = 0: successful exit */ 00088 /* < 0: if INFO = -i, the i-th argument had an illegal value */ 00089 /* > 0: if INFO = i, the i-th diagonal element is nonpositive. */ 00090 00091 /* ===================================================================== */ 00092 00093 /* .. Parameters .. */ 00094 /* .. */ 00095 /* .. Local Scalars .. */ 00096 /* .. */ 00097 /* .. External Functions .. */ 00098 /* .. */ 00099 /* .. External Subroutines .. */ 00100 /* .. */ 00101 /* .. Intrinsic Functions .. */ 00102 /* .. */ 00103 /* .. Executable Statements .. */ 00104 00105 /* Test the input parameters. */ 00106 00107 /* Positive definite only performs 1 pass of equilibration. */ 00108 00109 /* Parameter adjustments */ 00110 a_dim1 = *lda; 00111 a_offset = 1 + a_dim1; 00112 a -= a_offset; 00113 --s; 00114 00115 /* Function Body */ 00116 *info = 0; 00117 if (*n < 0) { 00118 *info = -1; 00119 } else if (*lda < max(1,*n)) { 00120 *info = -3; 00121 } 00122 if (*info != 0) { 00123 i__1 = -(*info); 00124 xerbla_("SPOEQUB", &i__1); 00125 return 0; 00126 } 00127 00128 /* Quick return if possible. */ 00129 00130 if (*n == 0) { 00131 *scond = 1.f; 00132 *amax = 0.f; 00133 return 0; 00134 } 00135 base = slamch_("B"); 00136 tmp = -.5f / log(base); 00137 00138 /* Find the minimum and maximum diagonal elements. */ 00139 00140 s[1] = a[a_dim1 + 1]; 00141 smin = s[1]; 00142 *amax = s[1]; 00143 i__1 = *n; 00144 for (i__ = 2; i__ <= i__1; ++i__) { 00145 s[i__] = a[i__ + i__ * a_dim1]; 00146 /* Computing MIN */ 00147 r__1 = smin, r__2 = s[i__]; 00148 smin = dmin(r__1,r__2); 00149 /* Computing MAX */ 00150 r__1 = *amax, r__2 = s[i__]; 00151 *amax = dmax(r__1,r__2); 00152 /* L10: */ 00153 } 00154 00155 if (smin <= 0.f) { 00156 00157 /* Find the first non-positive diagonal element and return. */ 00158 00159 i__1 = *n; 00160 for (i__ = 1; i__ <= i__1; ++i__) { 00161 if (s[i__] <= 0.f) { 00162 *info = i__; 00163 return 0; 00164 } 00165 /* L20: */ 00166 } 00167 } else { 00168 00169 /* Set the scale factors to the reciprocals */ 00170 /* of the diagonal elements. */ 00171 00172 i__1 = *n; 00173 for (i__ = 1; i__ <= i__1; ++i__) { 00174 i__2 = (integer) (tmp * log(s[i__])); 00175 s[i__] = pow_ri(&base, &i__2); 00176 /* L30: */ 00177 } 00178 00179 /* Compute SCOND = min(S(I)) / max(S(I)). */ 00180 00181 *scond = sqrt(smin) / sqrt(*amax); 00182 } 00183 00184 return 0; 00185 00186 /* End of SPOEQUB */ 00187 00188 } /* spoequb_ */