LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
ssyequb.f
Go to the documentation of this file.
1*> \brief \b SSYEQUB
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download SSYEQUB + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ssyequb.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ssyequb.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ssyequb.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE SSYEQUB( UPLO, N, A, LDA, S, SCOND, AMAX, WORK, INFO )
20*
21* .. Scalar Arguments ..
22* INTEGER INFO, LDA, N
23* REAL AMAX, SCOND
24* CHARACTER UPLO
25* ..
26* .. Array Arguments ..
27* REAL A( LDA, * ), S( * ), WORK( * )
28* ..
29*
30*
31*> \par Purpose:
32* =============
33*>
34*> \verbatim
35*>
36*> SSYEQUB computes row and column scalings intended to equilibrate a
37*> symmetric matrix A (with respect to the Euclidean norm) and reduce
38*> its condition number. The scale factors S are computed by the BIN
39*> algorithm (see references) so that the scaled matrix B with elements
40*> B(i,j) = S(i)*A(i,j)*S(j) has a condition number within a factor N of
41*> the smallest possible condition number over all possible diagonal
42*> scalings.
43*> \endverbatim
44*
45* Arguments:
46* ==========
47*
48*> \param[in] UPLO
49*> \verbatim
50*> UPLO is CHARACTER*1
51*> = 'U': Upper triangle of A is stored;
52*> = 'L': Lower triangle of A is stored.
53*> \endverbatim
54*>
55*> \param[in] N
56*> \verbatim
57*> N is INTEGER
58*> The order of the matrix A. N >= 0.
59*> \endverbatim
60*>
61*> \param[in] A
62*> \verbatim
63*> A is REAL array, dimension (LDA,N)
64*> The N-by-N symmetric matrix whose scaling factors are to be
65*> computed.
66*> \endverbatim
67*>
68*> \param[in] LDA
69*> \verbatim
70*> LDA is INTEGER
71*> The leading dimension of the array A. LDA >= max(1,N).
72*> \endverbatim
73*>
74*> \param[out] S
75*> \verbatim
76*> S is REAL array, dimension (N)
77*> If INFO = 0, S contains the scale factors for A.
78*> \endverbatim
79*>
80*> \param[out] SCOND
81*> \verbatim
82*> SCOND is REAL
83*> If INFO = 0, S contains the ratio of the smallest S(i) to
84*> the largest S(i). If SCOND >= 0.1 and AMAX is neither too
85*> large nor too small, it is not worth scaling by S.
86*> \endverbatim
87*>
88*> \param[out] AMAX
89*> \verbatim
90*> AMAX is REAL
91*> Largest absolute value of any matrix element. If AMAX is
92*> very close to overflow or very close to underflow, the
93*> matrix should be scaled.
94*> \endverbatim
95*>
96*> \param[out] WORK
97*> \verbatim
98*> WORK is REAL array, dimension (2*N)
99*> \endverbatim
100*>
101*> \param[out] INFO
102*> \verbatim
103*> INFO is INTEGER
104*> = 0: successful exit
105*> < 0: if INFO = -i, the i-th argument had an illegal value
106*> > 0: if INFO = i, the i-th diagonal element is nonpositive.
107*> \endverbatim
108*
109* Authors:
110* ========
111*
112*> \author Univ. of Tennessee
113*> \author Univ. of California Berkeley
114*> \author Univ. of Colorado Denver
115*> \author NAG Ltd.
116*
117*> \ingroup heequb
118*
119*> \par References:
120* ================
121*>
122*> Livne, O.E. and Golub, G.H., "Scaling by Binormalization", \n
123*> Numerical Algorithms, vol. 35, no. 1, pp. 97-120, January 2004. \n
124*> DOI 10.1023/B:NUMA.0000016606.32820.69 \n
125*> Tech report version: http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.3.1679
126*>
127* =====================================================================
128 SUBROUTINE ssyequb( UPLO, N, A, LDA, S, SCOND, AMAX, WORK,
129 $ INFO )
130*
131* -- LAPACK computational routine --
132* -- LAPACK is a software package provided by Univ. of Tennessee, --
133* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
134*
135* .. Scalar Arguments ..
136 INTEGER INFO, LDA, N
137 REAL AMAX, SCOND
138 CHARACTER UPLO
139* ..
140* .. Array Arguments ..
141 REAL A( LDA, * ), S( * ), WORK( * )
142* ..
143*
144* =====================================================================
145*
146* .. Parameters ..
147 REAL ONE, ZERO
148 parameter( one = 1.0e0, zero = 0.0e0 )
149 INTEGER MAX_ITER
150 parameter( max_iter = 100 )
151* ..
152* .. Local Scalars ..
153 INTEGER I, J, ITER
154 REAL AVG, STD, TOL, C0, C1, C2, T, U, SI, D, BASE,
155 $ smin, smax, smlnum, bignum, scale, sumsq
156 LOGICAL UP
157* ..
158* .. External Functions ..
159 REAL SLAMCH
160 LOGICAL LSAME
161 EXTERNAL lsame, slamch
162* ..
163* .. External Subroutines ..
164 EXTERNAL slassq, xerbla
165* ..
166* .. Intrinsic Functions ..
167 INTRINSIC abs, int, log, max, min, sqrt
168* ..
169* .. Executable Statements ..
170*
171* Test the input parameters.
172*
173 info = 0
174 IF ( .NOT. ( lsame( uplo, 'U' ) .OR.
175 $ lsame( uplo, 'L' ) ) ) THEN
176 info = -1
177 ELSE IF ( n .LT. 0 ) THEN
178 info = -2
179 ELSE IF ( lda .LT. max( 1, n ) ) THEN
180 info = -4
181 END IF
182 IF ( info .NE. 0 ) THEN
183 CALL xerbla( 'SSYEQUB', -info )
184 RETURN
185 END IF
186
187 up = lsame( uplo, 'U' )
188 amax = zero
189*
190* Quick return if possible.
191*
192 IF ( n .EQ. 0 ) THEN
193 scond = one
194 RETURN
195 END IF
196
197 DO i = 1, n
198 s( i ) = zero
199 END DO
200
201 amax = zero
202 IF ( up ) THEN
203 DO j = 1, n
204 DO i = 1, j-1
205 s( i ) = max( s( i ), abs( a( i, j ) ) )
206 s( j ) = max( s( j ), abs( a( i, j ) ) )
207 amax = max( amax, abs( a( i, j ) ) )
208 END DO
209 s( j ) = max( s( j ), abs( a( j, j ) ) )
210 amax = max( amax, abs( a( j, j ) ) )
211 END DO
212 ELSE
213 DO j = 1, n
214 s( j ) = max( s( j ), abs( a( j, j ) ) )
215 amax = max( amax, abs( a( j, j ) ) )
216 DO i = j+1, n
217 s( i ) = max( s( i ), abs( a( i, j ) ) )
218 s( j ) = max( s( j ), abs( a( i, j ) ) )
219 amax = max( amax, abs( a( i, j ) ) )
220 END DO
221 END DO
222 END IF
223 DO j = 1, n
224 s( j ) = 1.0e0 / s( j )
225 END DO
226
227 tol = one / sqrt( 2.0e0 * real( n ) )
228
229 DO iter = 1, max_iter
230 scale = 0.0e0
231 sumsq = 0.0e0
232* beta = |A|s
233 DO i = 1, n
234 work( i ) = zero
235 END DO
236 IF ( up ) THEN
237 DO j = 1, n
238 DO i = 1, j-1
239 work( i ) = work( i ) + abs( a( i, j ) ) * s( j )
240 work( j ) = work( j ) + abs( a( i, j ) ) * s( i )
241 END DO
242 work( j ) = work( j ) + abs( a( j, j ) ) * s( j )
243 END DO
244 ELSE
245 DO j = 1, n
246 work( j ) = work( j ) + abs( a( j, j ) ) * s( j )
247 DO i = j+1, n
248 work( i ) = work( i ) + abs( a( i, j ) ) * s( j )
249 work( j ) = work( j ) + abs( a( i, j ) ) * s( i )
250 END DO
251 END DO
252 END IF
253
254* avg = s^T beta / n
255 avg = 0.0e0
256 DO i = 1, n
257 avg = avg + s( i )*work( i )
258 END DO
259 avg = avg / real( n )
260
261 std = 0.0e0
262 DO i = n+1, 2*n
263 work( i ) = s( i-n ) * work( i-n ) - avg
264 END DO
265 CALL slassq( n, work( n+1 ), 1, scale, sumsq )
266 std = scale * sqrt( sumsq / real( n ) )
267
268 IF ( std .LT. tol * avg ) GOTO 999
269
270 DO i = 1, n
271 t = abs( a( i, i ) )
272 si = s( i )
273 c2 = real( n-1 ) * t
274 c1 = real( n-2 ) * ( work( i ) - t*si )
275 c0 = -(t*si)*si + 2*work( i )*si - real( n )*avg
276 d = c1*c1 - 4*c0*c2
277
278 IF ( d .LE. 0 ) THEN
279 info = -1
280 RETURN
281 END IF
282 si = -2*c0 / ( c1 + sqrt( d ) )
283
284 d = si - s( i )
285 u = zero
286 IF ( up ) THEN
287 DO j = 1, i
288 t = abs( a( j, i ) )
289 u = u + s( j )*t
290 work( j ) = work( j ) + d*t
291 END DO
292 DO j = i+1,n
293 t = abs( a( i, j ) )
294 u = u + s( j )*t
295 work( j ) = work( j ) + d*t
296 END DO
297 ELSE
298 DO j = 1, i
299 t = abs( a( i, j ) )
300 u = u + s( j )*t
301 work( j ) = work( j ) + d*t
302 END DO
303 DO j = i+1,n
304 t = abs( a( j, i ) )
305 u = u + s( j )*t
306 work( j ) = work( j ) + d*t
307 END DO
308 END IF
309
310 avg = avg + ( u + work( i ) ) * d / real( n )
311 s( i ) = si
312 END DO
313 END DO
314
315 999 CONTINUE
316
317 smlnum = slamch( 'SAFEMIN' )
318 bignum = one / smlnum
319 smin = bignum
320 smax = zero
321 t = one / sqrt( avg )
322 base = slamch( 'B' )
323 u = one / log( base )
324 DO i = 1, n
325 s( i ) = base ** int( u * log( s( i ) * t ) )
326 smin = min( smin, s( i ) )
327 smax = max( smax, s( i ) )
328 END DO
329 scond = max( smin, smlnum ) / min( smax, bignum )
330*
331 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine ssyequb(uplo, n, a, lda, s, scond, amax, work, info)
SSYEQUB
Definition ssyequb.f:130
subroutine slassq(n, x, incx, scale, sumsq)
SLASSQ updates a sum of squares represented in scaled form.
Definition slassq.f90:122