132
133
134
135
136
137
138 INTEGER INFO, LDA, N
139 DOUBLE PRECISION AMAX, SCOND
140 CHARACTER UPLO
141
142
143 COMPLEX*16 A( LDA, * ), WORK( * )
144 DOUBLE PRECISION S( * )
145
146
147
148
149
150 DOUBLE PRECISION ONE, ZERO
151 parameter( one = 1.0d0, zero = 0.0d0 )
152 INTEGER MAX_ITER
153 parameter( max_iter = 100 )
154
155
156 INTEGER I, J, ITER
157 DOUBLE PRECISION AVG, STD, TOL, C0, C1, C2, T, U, SI, D, BASE,
158 $ SMIN, SMAX, SMLNUM, BIGNUM, SCALE, SUMSQ
159 LOGICAL UP
160 COMPLEX*16 ZDUM
161
162
163 DOUBLE PRECISION DLAMCH
164 LOGICAL LSAME
166
167
169
170
171 INTRINSIC abs, dble, dimag, int, log, max, min, sqrt
172
173
174 DOUBLE PRECISION CABS1
175
176
177 cabs1( zdum ) = abs( dble( zdum ) ) + abs( dimag( 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(
'ZSYEQUB', -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.0d0 / s( j )
234 END DO
235
236 tol = one / sqrt( 2.0d0 * n )
237
238 DO iter = 1, max_iter
239 scale = 0.0d0
240 sumsq = 0.0d0
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.0d0
265 DO i = 1, n
266 avg = avg + s( i ) * dble( work( i ) )
267 END DO
268 avg = avg / n
269
270 std = 0.0d0
271 DO i = n+1, 2*n
272 work( i ) = s( i-n ) * work( i-n ) - avg
273 END DO
274 CALL zlassq( 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 = ( n-2 ) * ( dble( work( i ) ) - t*si )
284 c0 = -(t*si)*si + 2 * dble( 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 + ( u + dble( work( i ) ) ) * d / n
320 s( i ) = si
321 END DO
322 END DO
323
324 999 CONTINUE
325
326 smlnum =
dlamch(
'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)
double precision function dlamch(cmach)
DLAMCH
subroutine zlassq(n, x, incx, scale, sumsq)
ZLASSQ updates a sum of squares represented in scaled form.
logical function lsame(ca, cb)
LSAME