00001 /* zpoequb.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 zpoequb_(integer *n, doublecomplex *a, integer *lda, 00017 doublereal *s, doublereal *scond, doublereal *amax, integer *info) 00018 { 00019 /* System generated locals */ 00020 integer a_dim1, a_offset, i__1, i__2, i__3; 00021 doublereal d__1, d__2; 00022 00023 /* Builtin functions */ 00024 double log(doublereal), pow_di(doublereal *, integer *), sqrt(doublereal); 00025 00026 /* Local variables */ 00027 integer i__; 00028 doublereal tmp, base, smin; 00029 extern doublereal dlamch_(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 /* ZPOEQUB 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) COMPLEX*16 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) DOUBLE PRECISION array, dimension (N) */ 00074 /* If INFO = 0, S contains the scale factors for A. */ 00075 00076 /* SCOND (output) DOUBLE PRECISION */ 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) DOUBLE PRECISION */ 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 /* .. Statement Functions .. */ 00104 /* .. */ 00105 /* .. Statement Function Definitions .. */ 00106 /* .. */ 00107 /* .. Executable Statements .. */ 00108 00109 /* Test the input parameters. */ 00110 00111 /* Positive definite only performs 1 pass of equilibration. */ 00112 00113 /* Parameter adjustments */ 00114 a_dim1 = *lda; 00115 a_offset = 1 + a_dim1; 00116 a -= a_offset; 00117 --s; 00118 00119 /* Function Body */ 00120 *info = 0; 00121 if (*n < 0) { 00122 *info = -1; 00123 } else if (*lda < max(1,*n)) { 00124 *info = -3; 00125 } 00126 if (*info != 0) { 00127 i__1 = -(*info); 00128 xerbla_("ZPOEQUB", &i__1); 00129 return 0; 00130 } 00131 00132 /* Quick return if possible. */ 00133 00134 if (*n == 0) { 00135 *scond = 1.; 00136 *amax = 0.; 00137 return 0; 00138 } 00139 base = dlamch_("B"); 00140 tmp = -.5 / log(base); 00141 00142 /* Find the minimum and maximum diagonal elements. */ 00143 00144 i__1 = a_dim1 + 1; 00145 s[1] = a[i__1].r; 00146 smin = s[1]; 00147 *amax = s[1]; 00148 i__1 = *n; 00149 for (i__ = 2; i__ <= i__1; ++i__) { 00150 i__2 = i__; 00151 i__3 = i__ + i__ * a_dim1; 00152 s[i__2] = a[i__3].r; 00153 /* Computing MIN */ 00154 d__1 = smin, d__2 = s[i__]; 00155 smin = min(d__1,d__2); 00156 /* Computing MAX */ 00157 d__1 = *amax, d__2 = s[i__]; 00158 *amax = max(d__1,d__2); 00159 /* L10: */ 00160 } 00161 00162 if (smin <= 0.) { 00163 00164 /* Find the first non-positive diagonal element and return. */ 00165 00166 i__1 = *n; 00167 for (i__ = 1; i__ <= i__1; ++i__) { 00168 if (s[i__] <= 0.) { 00169 *info = i__; 00170 return 0; 00171 } 00172 /* L20: */ 00173 } 00174 } else { 00175 00176 /* Set the scale factors to the reciprocals */ 00177 /* of the diagonal elements. */ 00178 00179 i__1 = *n; 00180 for (i__ = 1; i__ <= i__1; ++i__) { 00181 i__2 = (integer) (tmp * log(s[i__])); 00182 s[i__] = pow_di(&base, &i__2); 00183 /* L30: */ 00184 } 00185 00186 /* Compute SCOND = min(S(I)) / max(S(I)). */ 00187 00188 *scond = sqrt(smin) / sqrt(*amax); 00189 } 00190 00191 return 0; 00192 00193 /* End of ZPOEQUB */ 00194 00195 } /* zpoequb_ */