00001 SUBROUTINE CSYEQUB( UPLO, N, A, LDA, S, SCOND, AMAX, WORK, INFO )
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 IMPLICIT NONE
00012
00013
00014 INTEGER INFO, LDA, N
00015 REAL AMAX, SCOND
00016 CHARACTER UPLO
00017
00018
00019 COMPLEX A( LDA, * ), WORK( * )
00020 REAL S( * )
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086 REAL ONE, ZERO
00087 PARAMETER ( ONE = 1.0E0, ZERO = 0.0E0 )
00088 INTEGER MAX_ITER
00089 PARAMETER ( MAX_ITER = 100 )
00090
00091
00092 INTEGER I, J, ITER
00093 REAL AVG, STD, TOL, C0, C1, C2, T, U, SI, D, BASE,
00094 $ SMIN, SMAX, SMLNUM, BIGNUM, SCALE, SUMSQ
00095 LOGICAL UP
00096 COMPLEX ZDUM
00097
00098
00099 REAL SLAMCH
00100 LOGICAL LSAME
00101 EXTERNAL LSAME, SLAMCH
00102
00103
00104 EXTERNAL CLASSQ
00105
00106
00107 INTRINSIC ABS, AIMAG, INT, LOG, MAX, MIN, REAL, SQRT
00108
00109
00110 REAL CABS1
00111
00112
00113 CABS1( ZDUM ) = ABS( REAL( ZDUM ) ) + ABS( AIMAG( ZDUM ) )
00114
00115
00116
00117
00118
00119 INFO = 0
00120 IF ( .NOT. ( LSAME( UPLO, 'U' ) .OR. LSAME( UPLO, 'L' ) ) ) THEN
00121 INFO = -1
00122 ELSE IF ( N .LT. 0 ) THEN
00123 INFO = -2
00124 ELSE IF ( LDA .LT. MAX( 1, N ) ) THEN
00125 INFO = -4
00126 END IF
00127 IF ( INFO .NE. 0 ) THEN
00128 CALL XERBLA( 'CSYEQUB', -INFO )
00129 RETURN
00130 END IF
00131
00132 UP = LSAME( UPLO, 'U' )
00133 AMAX = ZERO
00134
00135
00136
00137 IF ( N .EQ. 0 ) THEN
00138 SCOND = ONE
00139 RETURN
00140 END IF
00141
00142 DO I = 1, N
00143 S( I ) = ZERO
00144 END DO
00145
00146 AMAX = ZERO
00147 IF ( UP ) THEN
00148 DO J = 1, N
00149 DO I = 1, J-1
00150 S( I ) = MAX( S( I ), CABS1( A( I, J ) ) )
00151 S( J ) = MAX( S( J ), CABS1( A( I, J ) ) )
00152 AMAX = MAX( AMAX, CABS1( A( I, J ) ) )
00153 END DO
00154 S( J ) = MAX( S( J ), CABS1( A( J, J) ) )
00155 AMAX = MAX( AMAX, CABS1( A( J, J ) ) )
00156 END DO
00157 ELSE
00158 DO J = 1, N
00159 S( J ) = MAX( S( J ), CABS1( A( J, J ) ) )
00160 AMAX = MAX( AMAX, CABS1( A( J, J ) ) )
00161 DO I = J+1, N
00162 S( I ) = MAX( S( I ), CABS1( A( I, J ) ) )
00163 S( J ) = MAX( S( J ), CABS1 (A( I, J ) ) )
00164 AMAX = MAX( AMAX, CABS1( A( I, J ) ) )
00165 END DO
00166 END DO
00167 END IF
00168 DO J = 1, N
00169 S( J ) = 1.0 / S( J )
00170 END DO
00171
00172 TOL = ONE / SQRT( 2.0E0 * N )
00173
00174 DO ITER = 1, MAX_ITER
00175 SCALE = 0.0
00176 SUMSQ = 0.0
00177
00178 DO I = 1, N
00179 WORK( I ) = ZERO
00180 END DO
00181 IF ( UP ) THEN
00182 DO J = 1, N
00183 DO I = 1, J-1
00184 T = CABS1( A( I, J ) )
00185 WORK( I ) = WORK( I ) + CABS1( A( I, J ) ) * S( J )
00186 WORK( J ) = WORK( J ) + CABS1( A( I, J ) ) * S( I )
00187 END DO
00188 WORK( J ) = WORK( J ) + CABS1( A( J, J ) ) * S( J )
00189 END DO
00190 ELSE
00191 DO J = 1, N
00192 WORK( J ) = WORK( J ) + CABS1( A( J, J ) ) * S( J )
00193 DO I = J+1, N
00194 T = CABS1( A( I, J ) )
00195 WORK( I ) = WORK( I ) + CABS1( A( I, J ) ) * S( J )
00196 WORK( J ) = WORK( J ) + CABS1( A( I, J ) ) * S( I )
00197 END DO
00198 END DO
00199 END IF
00200
00201
00202 AVG = 0.0
00203 DO I = 1, N
00204 AVG = AVG + S( I )*WORK( I )
00205 END DO
00206 AVG = AVG / N
00207
00208 STD = 0.0
00209 DO I = N+1, 2*N
00210 WORK( I ) = S( I-N ) * WORK( I-N ) - AVG
00211 END DO
00212 CALL CLASSQ( N, WORK( N+1 ), 1, SCALE, SUMSQ )
00213 STD = SCALE * SQRT( SUMSQ / N )
00214
00215 IF ( STD .LT. TOL * AVG ) GOTO 999
00216
00217 DO I = 1, N
00218 T = CABS1( A( I, I ) )
00219 SI = S( I )
00220 C2 = ( N-1 ) * T
00221 C1 = ( N-2 ) * ( WORK( I ) - T*SI )
00222 C0 = -(T*SI)*SI + 2*WORK( I )*SI - N*AVG
00223 D = C1*C1 - 4*C0*C2
00224
00225 IF ( D .LE. 0 ) THEN
00226 INFO = -1
00227 RETURN
00228 END IF
00229 SI = -2*C0 / ( C1 + SQRT( D ) )
00230
00231 D = SI - S( I )
00232 U = ZERO
00233 IF ( UP ) THEN
00234 DO J = 1, I
00235 T = CABS1( A( J, I ) )
00236 U = U + S( J )*T
00237 WORK( J ) = WORK( J ) + D*T
00238 END DO
00239 DO J = I+1,N
00240 T = CABS1( A( I, J ) )
00241 U = U + S( J )*T
00242 WORK( J ) = WORK( J ) + D*T
00243 END DO
00244 ELSE
00245 DO J = 1, I
00246 T = CABS1( A( I, J ) )
00247 U = U + S( J )*T
00248 WORK( J ) = WORK( J ) + D*T
00249 END DO
00250 DO J = I+1,N
00251 T = CABS1( A( J, I ) )
00252 U = U + S( J )*T
00253 WORK( J ) = WORK( J ) + D*T
00254 END DO
00255 END IF
00256 AVG = AVG + ( U + WORK( I ) ) * D / N
00257 S( I ) = SI
00258 END DO
00259 END DO
00260
00261 999 CONTINUE
00262
00263 SMLNUM = SLAMCH( 'SAFEMIN' )
00264 BIGNUM = ONE / SMLNUM
00265 SMIN = BIGNUM
00266 SMAX = ZERO
00267 T = ONE / SQRT( AVG )
00268 BASE = SLAMCH( 'B' )
00269 U = ONE / LOG( BASE )
00270 DO I = 1, N
00271 S( I ) = BASE ** INT( U * LOG( S( I ) * T ) )
00272 SMIN = MIN( SMIN, S( I ) )
00273 SMAX = MAX( SMAX, S( I ) )
00274 END DO
00275 SCOND = MAX( SMIN, SMLNUM ) / MIN( SMAX, BIGNUM )
00276
00277 END