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