132
133
134
135
136
137
138 INTEGER INFO, LDA, N
139 REAL AMAX, SCOND
140 CHARACTER UPLO
141
142
143 COMPLEX A( LDA, * ), WORK( * )
144 REAL S( * )
145
146
147
148
149
150 REAL ONE, ZERO
151 parameter( one = 1.0e0, zero = 0.0e0 )
152 INTEGER MAX_ITER
153 parameter( max_iter = 100 )
154
155
156 INTEGER I, J, ITER
157 REAL AVG, STD, TOL, C0, C1, C2, T, U, SI, D, BASE,
158 $ SMIN, SMAX, SMLNUM, BIGNUM, SCALE, SUMSQ
159 LOGICAL UP
160 COMPLEX ZDUM
161
162
163 REAL SLAMCH
164 LOGICAL LSAME
166
167
169
170
171 INTRINSIC abs, aimag, int, log, max, min, real, sqrt
172
173
174 REAL CABS1
175
176
177 cabs1( zdum ) = abs( real( zdum ) ) + abs( aimag( zdum ) )
178
179
180
181
182
183 info = 0
184 IF ( .NOT. (
lsame( uplo,
'U' ) .OR.
lsame( uplo,
'L' ) ) )
THEN
185 info = -1
186 ELSE IF ( n .LT. 0 ) THEN
187 info = -2
188 ELSE IF ( lda .LT. max( 1, n ) ) THEN
189 info = -4
190 END IF
191 IF ( info .NE. 0 ) THEN
192 CALL xerbla(
'CHEEQUB', -info )
193 RETURN
194 END IF
195
196 up =
lsame( uplo,
'U' )
197 amax = zero
198
199
200
201 IF ( n .EQ. 0 ) THEN
202 scond = one
203 RETURN
204 END IF
205
206 DO i = 1, n
207 s( i ) = zero
208 END DO
209
210 amax = zero
211 IF ( up ) THEN
212 DO j = 1, n
213 DO i = 1, j-1
214 s( i ) = max( s( i ), cabs1( a( i, j ) ) )
215 s( j ) = max( s( j ), cabs1( a( i, j ) ) )
216 amax = max( amax, cabs1( a( i, j ) ) )
217 END DO
218 s( j ) = max( s( j ), cabs1( a( j, j ) ) )
219 amax = max( amax, cabs1( a( j, j ) ) )
220 END DO
221 ELSE
222 DO j = 1, n
223 s( j ) = max( s( j ), cabs1( a( j, j ) ) )
224 amax = max( amax, cabs1( a( j, j ) ) )
225 DO i = j+1, n
226 s( i ) = max( s( i ), cabs1( a( i, j ) ) )
227 s( j ) = max( s( j ), cabs1( a( i, j ) ) )
228 amax = max( amax, cabs1( a( i, j ) ) )
229 END DO
230 END DO
231 END IF
232 DO j = 1, n
233 s( j ) = 1.0e0 / s( j )
234 END DO
235
236 tol = one / sqrt( 2.0e0 * n )
237
238 DO iter = 1, max_iter
239 scale = 0.0e0
240 sumsq = 0.0e0
241
242 DO i = 1, n
243 work( i ) = zero
244 END DO
245 IF ( up ) THEN
246 DO j = 1, n
247 DO i = 1, j-1
248 work( i ) = work( i ) + cabs1( a( i, j ) ) * s( j )
249 work( j ) = work( j ) + cabs1( a( i, j ) ) * s( i )
250 END DO
251 work( j ) = work( j ) + cabs1( a( j, j ) ) * s( j )
252 END DO
253 ELSE
254 DO j = 1, n
255 work( j ) = work( j ) + cabs1( a( j, j ) ) * s( j )
256 DO i = j+1, n
257 work( i ) = work( i ) + cabs1( a( i, j ) ) * s( j )
258 work( j ) = work( j ) + cabs1( a( i, j ) ) * s( i )
259 END DO
260 END DO
261 END IF
262
263
264 avg = 0.0e0
265 DO i = 1, n
266 avg = avg + real( s( i )*work( i ) )
267 END DO
268 avg = avg / n
269
270 std = 0.0e0
271 DO i = n+1, 2*n
272 work( i ) = s( i-n ) * work( i-n ) - avg
273 END DO
274 CALL classq( n, work( n+1 ), 1, scale, sumsq )
275 std = scale * sqrt( sumsq / n )
276
277 IF ( std .LT. tol * avg ) GOTO 999
278
279 DO i = 1, n
280 t = cabs1( a( i, i ) )
281 si = s( i )
282 c2 = ( n-1 ) * t
283 c1 = real( ( n-2 ) * ( work( i ) - t*si ) )
284 c0 = real( -(t*si)*si + 2*work( i )*si - n*avg )
285 d = c1*c1 - 4*c0*c2
286
287 IF ( d .LE. 0 ) THEN
288 info = -1
289 RETURN
290 END IF
291 si = -2*c0 / ( c1 + sqrt( d ) )
292
293 d = si - s( i )
294 u = zero
295 IF ( up ) THEN
296 DO j = 1, i
297 t = cabs1( a( j, i ) )
298 u = u + s( j )*t
299 work( j ) = work( j ) + d*t
300 END DO
301 DO j = i+1,n
302 t = cabs1( a( i, j ) )
303 u = u + s( j )*t
304 work( j ) = work( j ) + d*t
305 END DO
306 ELSE
307 DO j = 1, i
308 t = cabs1( a( i, j ) )
309 u = u + s( j )*t
310 work( j ) = work( j ) + d*t
311 END DO
312 DO j = i+1,n
313 t = cabs1( a( j, i ) )
314 u = u + s( j )*t
315 work( j ) = work( j ) + d*t
316 END DO
317 END IF
318
319 avg = avg + real( ( u + work( i ) ) * d / n )
320 s( i ) = si
321 END DO
322 END DO
323
324 999 CONTINUE
325
326 smlnum =
slamch(
'SAFEMIN' )
327 bignum = one / smlnum
328 smin = bignum
329 smax = zero
330 t = one / sqrt( avg )
332 u = one / log( base )
333 DO i = 1, n
334 s( i ) = base ** int( u * log( s( i ) * t ) )
335 smin = min( smin, s( i ) )
336 smax = max( smax, s( i ) )
337 END DO
338 scond = max( smin, smlnum ) / min( smax, bignum )
339
subroutine xerbla(srname, info)
real function slamch(cmach)
SLAMCH
subroutine classq(n, x, incx, scale, sumsq)
CLASSQ updates a sum of squares represented in scaled form.
logical function lsame(ca, cb)
LSAME