![]() |
LAPACK
3.4.1
LAPACK: Linear Algebra PACKage
|
00001 *> \brief \b DSYEQUB 00002 * 00003 * =========== DOCUMENTATION =========== 00004 * 00005 * Online html documentation available at 00006 * http://www.netlib.org/lapack/explore-html/ 00007 * 00008 *> \htmlonly 00009 *> Download DSYEQUB + dependencies 00010 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dsyequb.f"> 00011 *> [TGZ]</a> 00012 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dsyequb.f"> 00013 *> [ZIP]</a> 00014 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dsyequb.f"> 00015 *> [TXT]</a> 00016 *> \endhtmlonly 00017 * 00018 * Definition: 00019 * =========== 00020 * 00021 * SUBROUTINE DSYEQUB( UPLO, N, A, LDA, S, SCOND, AMAX, WORK, INFO ) 00022 * 00023 * .. Scalar Arguments .. 00024 * INTEGER INFO, LDA, N 00025 * DOUBLE PRECISION AMAX, SCOND 00026 * CHARACTER UPLO 00027 * .. 00028 * .. Array Arguments .. 00029 * DOUBLE PRECISION A( LDA, * ), S( * ), WORK( * ) 00030 * .. 00031 * 00032 * 00033 *> \par Purpose: 00034 * ============= 00035 *> 00036 *> \verbatim 00037 *> 00038 *> DSYEQUB computes row and column scalings intended to equilibrate a 00039 *> symmetric matrix A and reduce its condition number 00040 *> (with respect to the two-norm). S contains the scale factors, 00041 *> S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with 00042 *> elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal. This 00043 *> choice of S puts the condition number of B within a factor N of the 00044 *> smallest possible condition number over all possible diagonal 00045 *> scalings. 00046 *> \endverbatim 00047 * 00048 * Arguments: 00049 * ========== 00050 * 00051 *> \param[in] UPLO 00052 *> \verbatim 00053 *> UPLO is CHARACTER*1 00054 *> Specifies whether the details of the factorization are stored 00055 *> as an upper or lower triangular matrix. 00056 *> = 'U': Upper triangular, form is A = U*D*U**T; 00057 *> = 'L': Lower triangular, form is A = L*D*L**T. 00058 *> \endverbatim 00059 *> 00060 *> \param[in] N 00061 *> \verbatim 00062 *> N is INTEGER 00063 *> The order of the matrix A. N >= 0. 00064 *> \endverbatim 00065 *> 00066 *> \param[in] A 00067 *> \verbatim 00068 *> A is DOUBLE PRECISION array, dimension (LDA,N) 00069 *> The N-by-N symmetric matrix whose scaling 00070 *> factors are to be computed. Only the diagonal elements of A 00071 *> are referenced. 00072 *> \endverbatim 00073 *> 00074 *> \param[in] LDA 00075 *> \verbatim 00076 *> LDA is INTEGER 00077 *> The leading dimension of the array A. LDA >= max(1,N). 00078 *> \endverbatim 00079 *> 00080 *> \param[out] S 00081 *> \verbatim 00082 *> S is DOUBLE PRECISION array, dimension (N) 00083 *> If INFO = 0, S contains the scale factors for A. 00084 *> \endverbatim 00085 *> 00086 *> \param[out] SCOND 00087 *> \verbatim 00088 *> SCOND is DOUBLE PRECISION 00089 *> If INFO = 0, S contains the ratio of the smallest S(i) to 00090 *> the largest S(i). If SCOND >= 0.1 and AMAX is neither too 00091 *> large nor too small, it is not worth scaling by S. 00092 *> \endverbatim 00093 *> 00094 *> \param[out] AMAX 00095 *> \verbatim 00096 *> AMAX is DOUBLE PRECISION 00097 *> Absolute value of largest matrix element. If AMAX is very 00098 *> close to overflow or very close to underflow, the matrix 00099 *> should be scaled. 00100 *> \endverbatim 00101 *> 00102 *> \param[out] WORK 00103 *> \verbatim 00104 *> WORK is DOUBLE PRECISION array, dimension (3*N) 00105 *> \endverbatim 00106 *> 00107 *> \param[out] INFO 00108 *> \verbatim 00109 *> INFO is INTEGER 00110 *> = 0: successful exit 00111 *> < 0: if INFO = -i, the i-th argument had an illegal value 00112 *> > 0: if INFO = i, the i-th diagonal element is nonpositive. 00113 *> \endverbatim 00114 * 00115 * Authors: 00116 * ======== 00117 * 00118 *> \author Univ. of Tennessee 00119 *> \author Univ. of California Berkeley 00120 *> \author Univ. of Colorado Denver 00121 *> \author NAG Ltd. 00122 * 00123 *> \date November 2011 00124 * 00125 *> \ingroup doubleSYcomputational 00126 * 00127 *> \par References: 00128 * ================ 00129 *> 00130 *> Livne, O.E. and Golub, G.H., "Scaling by Binormalization", \n 00131 *> Numerical Algorithms, vol. 35, no. 1, pp. 97-120, January 2004. \n 00132 *> DOI 10.1023/B:NUMA.0000016606.32820.69 \n 00133 *> Tech report version: http://ruready.utah.edu/archive/papers/bin.pdf 00134 *> 00135 * ===================================================================== 00136 SUBROUTINE DSYEQUB( UPLO, N, A, LDA, S, SCOND, AMAX, WORK, INFO ) 00137 * 00138 * -- LAPACK computational routine (version 3.4.0) -- 00139 * -- LAPACK is a software package provided by Univ. of Tennessee, -- 00140 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- 00141 * November 2011 00142 * 00143 * .. Scalar Arguments .. 00144 INTEGER INFO, LDA, N 00145 DOUBLE PRECISION AMAX, SCOND 00146 CHARACTER UPLO 00147 * .. 00148 * .. Array Arguments .. 00149 DOUBLE PRECISION A( LDA, * ), S( * ), WORK( * ) 00150 * .. 00151 * 00152 * ===================================================================== 00153 * 00154 * .. Parameters .. 00155 DOUBLE PRECISION ONE, ZERO 00156 PARAMETER ( ONE = 1.0D+0, ZERO = 0.0D+0 ) 00157 INTEGER MAX_ITER 00158 PARAMETER ( MAX_ITER = 100 ) 00159 * .. 00160 * .. Local Scalars .. 00161 INTEGER I, J, ITER 00162 DOUBLE PRECISION AVG, STD, TOL, C0, C1, C2, T, U, SI, D, BASE, 00163 $ SMIN, SMAX, SMLNUM, BIGNUM, SCALE, SUMSQ 00164 LOGICAL UP 00165 * .. 00166 * .. External Functions .. 00167 DOUBLE PRECISION DLAMCH 00168 LOGICAL LSAME 00169 EXTERNAL DLAMCH, LSAME 00170 * .. 00171 * .. External Subroutines .. 00172 EXTERNAL DLASSQ 00173 * .. 00174 * .. Intrinsic Functions .. 00175 INTRINSIC ABS, INT, LOG, MAX, MIN, SQRT 00176 * .. 00177 * .. Executable Statements .. 00178 * 00179 * Test input parameters. 00180 * 00181 INFO = 0 00182 IF ( .NOT. ( LSAME( UPLO, 'U' ) .OR. LSAME( UPLO, 'L' ) ) ) THEN 00183 INFO = -1 00184 ELSE IF ( N .LT. 0 ) THEN 00185 INFO = -2 00186 ELSE IF ( LDA .LT. MAX( 1, N ) ) THEN 00187 INFO = -4 00188 END IF 00189 IF ( INFO .NE. 0 ) THEN 00190 CALL XERBLA( 'DSYEQUB', -INFO ) 00191 RETURN 00192 END IF 00193 00194 UP = LSAME( UPLO, 'U' ) 00195 AMAX = ZERO 00196 * 00197 * Quick return if possible. 00198 * 00199 IF ( N .EQ. 0 ) THEN 00200 SCOND = ONE 00201 RETURN 00202 END IF 00203 00204 DO I = 1, N 00205 S( I ) = ZERO 00206 END DO 00207 00208 AMAX = ZERO 00209 IF ( UP ) THEN 00210 DO J = 1, N 00211 DO I = 1, J-1 00212 S( I ) = MAX( S( I ), ABS( A( I, J ) ) ) 00213 S( J ) = MAX( S( J ), ABS( A( I, J ) ) ) 00214 AMAX = MAX( AMAX, ABS( A(I, J) ) ) 00215 END DO 00216 S( J ) = MAX( S( J ), ABS( A( J, J ) ) ) 00217 AMAX = MAX( AMAX, ABS( A( J, J ) ) ) 00218 END DO 00219 ELSE 00220 DO J = 1, N 00221 S( J ) = MAX( S( J ), ABS( A( J, J ) ) ) 00222 AMAX = MAX( AMAX, ABS( A( J, J ) ) ) 00223 DO I = J+1, N 00224 S( I ) = MAX( S( I ), ABS( A( I, J ) ) ) 00225 S( J ) = MAX( S( J ), ABS( A( I, J ) ) ) 00226 AMAX = MAX( AMAX, ABS( A( I, J ) ) ) 00227 END DO 00228 END DO 00229 END IF 00230 DO J = 1, N 00231 S( J ) = 1.0D+0 / S( J ) 00232 END DO 00233 00234 TOL = ONE / SQRT(2.0D0 * N) 00235 00236 DO ITER = 1, MAX_ITER 00237 SCALE = 0.0D+0 00238 SUMSQ = 0.0D+0 00239 * BETA = |A|S 00240 DO I = 1, N 00241 WORK(I) = ZERO 00242 END DO 00243 IF ( UP ) THEN 00244 DO J = 1, N 00245 DO I = 1, J-1 00246 T = ABS( A( I, J ) ) 00247 WORK( I ) = WORK( I ) + ABS( A( I, J ) ) * S( J ) 00248 WORK( J ) = WORK( J ) + ABS( A( I, J ) ) * S( I ) 00249 END DO 00250 WORK( J ) = WORK( J ) + ABS( A( J, J ) ) * S( J ) 00251 END DO 00252 ELSE 00253 DO J = 1, N 00254 WORK( J ) = WORK( J ) + ABS( A( J, J ) ) * S( J ) 00255 DO I = J+1, N 00256 T = ABS( A( I, J ) ) 00257 WORK( I ) = WORK( I ) + ABS( A( I, J ) ) * S( J ) 00258 WORK( J ) = WORK( J ) + ABS( A( I, J ) ) * S( I ) 00259 END DO 00260 END DO 00261 END IF 00262 00263 * avg = s^T beta / n 00264 AVG = 0.0D+0 00265 DO I = 1, N 00266 AVG = AVG + S( I )*WORK( I ) 00267 END DO 00268 AVG = AVG / N 00269 00270 STD = 0.0D+0 00271 DO I = 2*N+1, 3*N 00272 WORK( I ) = S( I-2*N ) * WORK( I-2*N ) - AVG 00273 END DO 00274 CALL DLASSQ( N, WORK( 2*N+1 ), 1, SCALE, SUMSQ ) 00275 STD = SCALE * SQRT( SUMSQ / N ) 00276 00277 IF ( STD .LT. TOL * AVG ) GOTO 999 00278 00279 DO I = 1, N 00280 T = ABS( A( I, I ) ) 00281 SI = S( I ) 00282 C2 = ( N-1 ) * T 00283 C1 = ( N-2 ) * ( WORK( I ) - T*SI ) 00284 C0 = -(T*SI)*SI + 2*WORK( I )*SI - N*AVG 00285 D = C1*C1 - 4*C0*C2 00286 00287 IF ( D .LE. 0 ) THEN 00288 INFO = -1 00289 RETURN 00290 END IF 00291 SI = -2*C0 / ( C1 + SQRT( D ) ) 00292 00293 D = SI - S( I ) 00294 U = ZERO 00295 IF ( UP ) THEN 00296 DO J = 1, I 00297 T = ABS( A( J, I ) ) 00298 U = U + S( J )*T 00299 WORK( J ) = WORK( J ) + D*T 00300 END DO 00301 DO J = I+1,N 00302 T = ABS( A( I, J ) ) 00303 U = U + S( J )*T 00304 WORK( J ) = WORK( J ) + D*T 00305 END DO 00306 ELSE 00307 DO J = 1, I 00308 T = ABS( A( I, J ) ) 00309 U = U + S( J )*T 00310 WORK( J ) = WORK( J ) + D*T 00311 END DO 00312 DO J = I+1,N 00313 T = ABS( A( J, I ) ) 00314 U = U + S( J )*T 00315 WORK( J ) = WORK( J ) + D*T 00316 END DO 00317 END IF 00318 00319 AVG = AVG + ( U + WORK( I ) ) * D / N 00320 S( I ) = SI 00321 00322 END DO 00323 00324 END DO 00325 00326 999 CONTINUE 00327 00328 SMLNUM = DLAMCH( 'SAFEMIN' ) 00329 BIGNUM = ONE / SMLNUM 00330 SMIN = BIGNUM 00331 SMAX = ZERO 00332 T = ONE / SQRT(AVG) 00333 BASE = DLAMCH( 'B' ) 00334 U = ONE / LOG( BASE ) 00335 DO I = 1, N 00336 S( I ) = BASE ** INT( U * LOG( S( I ) * T ) ) 00337 SMIN = MIN( SMIN, S( I ) ) 00338 SMAX = MAX( SMAX, S( I ) ) 00339 END DO 00340 SCOND = MAX( SMIN, SMLNUM ) / MIN( SMAX, BIGNUM ) 00341 * 00342 END