1: *> \brief \b ZSYEQUB
2: *
3: * =========== DOCUMENTATION ===========
4: *
5: * Online html documentation available at
6: * http://www.netlib.org/lapack/explore-html/
7: *
8: *> \htmlonly
9: *> Download ZSYEQUB + dependencies
10: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zsyequb.f">
11: *> [TGZ]</a>
12: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zsyequb.f">
13: *> [ZIP]</a>
14: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zsyequb.f">
15: *> [TXT]</a>
16: *> \endhtmlonly
17: *
18: * Definition:
19: * ===========
20: *
21: * SUBROUTINE ZSYEQUB( UPLO, N, A, LDA, S, SCOND, AMAX, WORK, INFO )
22: *
23: * .. Scalar Arguments ..
24: * INTEGER INFO, LDA, N
25: * DOUBLE PRECISION AMAX, SCOND
26: * CHARACTER UPLO
27: * ..
28: * .. Array Arguments ..
29: * COMPLEX*16 A( LDA, * ), WORK( * )
30: * DOUBLE PRECISION S( * )
31: * ..
32: *
33: *
34: *> \par Purpose:
35: * =============
36: *>
37: *> \verbatim
38: *>
39: *> ZSYEQUB computes row and column scalings intended to equilibrate a
40: *> symmetric matrix A and reduce its condition number
41: *> (with respect to the two-norm). S contains the scale factors,
42: *> S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with
43: *> elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal. This
44: *> choice of S puts the condition number of B within a factor N of the
45: *> smallest possible condition number over all possible diagonal
46: *> scalings.
47: *> \endverbatim
48: *
49: * Arguments:
50: * ==========
51: *
52: *> \param[in] UPLO
53: *> \verbatim
54: *> UPLO is CHARACTER*1
55: *> Specifies whether the details of the factorization are stored
56: *> as an upper or lower triangular matrix.
57: *> = 'U': Upper triangular, form is A = U*D*U**T;
58: *> = 'L': Lower triangular, form is A = L*D*L**T.
59: *> \endverbatim
60: *>
61: *> \param[in] N
62: *> \verbatim
63: *> N is INTEGER
64: *> The order of the matrix A. N >= 0.
65: *> \endverbatim
66: *>
67: *> \param[in] A
68: *> \verbatim
69: *> A is COMPLEX*16 array, dimension (LDA,N)
70: *> The N-by-N symmetric matrix whose scaling
71: *> factors are to be computed. Only the diagonal elements of A
72: *> are referenced.
73: *> \endverbatim
74: *>
75: *> \param[in] LDA
76: *> \verbatim
77: *> LDA is INTEGER
78: *> The leading dimension of the array A. LDA >= max(1,N).
79: *> \endverbatim
80: *>
81: *> \param[out] S
82: *> \verbatim
83: *> S is DOUBLE PRECISION array, dimension (N)
84: *> If INFO = 0, S contains the scale factors for A.
85: *> \endverbatim
86: *>
87: *> \param[out] SCOND
88: *> \verbatim
89: *> SCOND is DOUBLE PRECISION
90: *> If INFO = 0, S contains the ratio of the smallest S(i) to
91: *> the largest S(i). If SCOND >= 0.1 and AMAX is neither too
92: *> large nor too small, it is not worth scaling by S.
93: *> \endverbatim
94: *>
95: *> \param[out] AMAX
96: *> \verbatim
97: *> AMAX is DOUBLE PRECISION
98: *> Absolute value of largest matrix element. If AMAX is very
99: *> close to overflow or very close to underflow, the matrix
100: *> should be scaled.
101: *> \endverbatim
102: *>
103: *> \param[out] WORK
104: *> \verbatim
105: *> WORK is COMPLEX*16 array, dimension (3*N)
106: *> \endverbatim
107: *>
108: *> \param[out] INFO
109: *> \verbatim
110: *> INFO is INTEGER
111: *> = 0: successful exit
112: *> < 0: if INFO = -i, the i-th argument had an illegal value
113: *> > 0: if INFO = i, the i-th diagonal element is nonpositive.
114: *> \endverbatim
115: *
116: * Authors:
117: * ========
118: *
119: *> \author Univ. of Tennessee
120: *> \author Univ. of California Berkeley
121: *> \author Univ. of Colorado Denver
122: *> \author NAG Ltd.
123: *
124: *> \date November 2011
125: *
126: *> \ingroup complex16SYcomputational
127: *
128: *> \par References:
129: * ================
130: *>
131: *> Livne, O.E. and Golub, G.H., "Scaling by Binormalization", \n
132: *> Numerical Algorithms, vol. 35, no. 1, pp. 97-120, January 2004. \n
133: *> DOI 10.1023/B:NUMA.0000016606.32820.69 \n
134: *> Tech report version: http://ruready.utah.edu/archive/papers/bin.pdf
135: *>
136: * =====================================================================
137: SUBROUTINE ZSYEQUB( UPLO, N, A, LDA, S, SCOND, AMAX, WORK, INFO )
138: *
139: * -- LAPACK computational routine (version 3.4.0) --
140: * -- LAPACK is a software package provided by Univ. of Tennessee, --
141: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
142: * November 2011
143: *
144: * .. Scalar Arguments ..
145: INTEGER INFO, LDA, N
146: DOUBLE PRECISION AMAX, SCOND
147: CHARACTER UPLO
148: * ..
149: * .. Array Arguments ..
150: COMPLEX*16 A( LDA, * ), WORK( * )
151: DOUBLE PRECISION S( * )
152: * ..
153: *
154: * =====================================================================
155: *
156: * .. Parameters ..
157: DOUBLE PRECISION ONE, ZERO
158: PARAMETER ( ONE = 1.0D0, ZERO = 0.0D0 )
159: INTEGER MAX_ITER
160: PARAMETER ( MAX_ITER = 100 )
161: * ..
162: * .. Local Scalars ..
163: INTEGER I, J, ITER
164: DOUBLE PRECISION AVG, STD, TOL, C0, C1, C2, T, U, SI, D, BASE,
165: $ SMIN, SMAX, SMLNUM, BIGNUM, SCALE, SUMSQ
166: LOGICAL UP
167: COMPLEX*16 ZDUM
168: * ..
169: * .. External Functions ..
170: DOUBLE PRECISION DLAMCH
171: LOGICAL LSAME
172: EXTERNAL DLAMCH, LSAME
173: * ..
174: * .. External Subroutines ..
175: EXTERNAL ZLASSQ
176: * ..
177: * .. Intrinsic Functions ..
178: INTRINSIC ABS, DBLE, DIMAG, INT, LOG, MAX, MIN, SQRT
179: * ..
180: * .. Statement Functions ..
181: DOUBLE PRECISION CABS1
182: * ..
183: * Statement Function Definitions
184: CABS1( ZDUM ) = ABS( DBLE( ZDUM ) ) + ABS( DIMAG( ZDUM ) )
185: * ..
186: * .. Executable Statements ..
187: *
188: * Test the input parameters.
189: *
190: INFO = 0
191: IF ( .NOT. ( LSAME( UPLO, 'U' ) .OR. LSAME( UPLO, 'L' ) ) ) THEN
192: INFO = -1
193: ELSE IF ( N .LT. 0 ) THEN
194: INFO = -2
195: ELSE IF ( LDA .LT. MAX( 1, N ) ) THEN
196: INFO = -4
197: END IF
198: IF ( INFO .NE. 0 ) THEN
199: CALL XERBLA( 'ZSYEQUB', -INFO )
200: RETURN
201: END IF
202:
203: UP = LSAME( UPLO, 'U' )
204: AMAX = ZERO
205: *
206: * Quick return if possible.
207: *
208: IF ( N .EQ. 0 ) THEN
209: SCOND = ONE
210: RETURN
211: END IF
212:
213: DO I = 1, N
214: S( I ) = ZERO
215: END DO
216:
217: AMAX = ZERO
218: IF ( UP ) THEN
219: DO J = 1, N
220: DO I = 1, J-1
221: S( I ) = MAX( S( I ), CABS1( A( I, J ) ) )
222: S( J ) = MAX( S( J ), CABS1( A( I, J ) ) )
223: AMAX = MAX( AMAX, CABS1( A( I, J ) ) )
224: END DO
225: S( J ) = MAX( S( J ), CABS1( A( J, J) ) )
226: AMAX = MAX( AMAX, CABS1( A( J, J ) ) )
227: END DO
228: ELSE
229: DO J = 1, N
230: S( J ) = MAX( S( J ), CABS1( A( J, J ) ) )
231: AMAX = MAX( AMAX, CABS1( A( J, J ) ) )
232: DO I = J+1, N
233: S( I ) = MAX( S( I ), CABS1( A( I, J ) ) )
234: S( J ) = MAX( S( J ), CABS1 (A( I, J ) ) )
235: AMAX = MAX( AMAX, CABS1( A( I, J ) ) )
236: END DO
237: END DO
238: END IF
239: DO J = 1, N
240: S( J ) = 1.0D+0 / S( J )
241: END DO
242:
243: TOL = ONE / SQRT( 2.0D0 * N )
244:
245: DO ITER = 1, MAX_ITER
246: SCALE = 0.0D+0
247: SUMSQ = 0.0D+0
248: * beta = |A|s
249: DO I = 1, N
250: WORK( I ) = ZERO
251: END DO
252: IF ( UP ) THEN
253: DO J = 1, N
254: DO I = 1, J-1
255: T = CABS1( A( I, J ) )
256: WORK( I ) = WORK( I ) + CABS1( A( I, J ) ) * S( J )
257: WORK( J ) = WORK( J ) + CABS1( A( I, J ) ) * S( I )
258: END DO
259: WORK( J ) = WORK( J ) + CABS1( A( J, J ) ) * S( J )
260: END DO
261: ELSE
262: DO J = 1, N
263: WORK( J ) = WORK( J ) + CABS1( A( J, J ) ) * S( J )
264: DO I = J+1, N
265: T = CABS1( A( I, J ) )
266: WORK( I ) = WORK( I ) + CABS1( A( I, J ) ) * S( J )
267: WORK( J ) = WORK( J ) + CABS1( A( I, J ) ) * S( I )
268: END DO
269: END DO
270: END IF
271:
272: * avg = s^T beta / n
273: AVG = 0.0D+0
274: DO I = 1, N
275: AVG = AVG + S( I )*WORK( I )
276: END DO
277: AVG = AVG / N
278:
279: STD = 0.0D+0
280: DO I = N+1, 2*N
281: WORK( I ) = S( I-N ) * WORK( I-N ) - AVG
282: END DO
283: CALL ZLASSQ( N, WORK( N+1 ), 1, SCALE, SUMSQ )
284: STD = SCALE * SQRT( SUMSQ / N )
285:
286: IF ( STD .LT. TOL * AVG ) GOTO 999
287:
288: DO I = 1, N
289: T = CABS1( A( I, I ) )
290: SI = S( I )
291: C2 = ( N-1 ) * T
292: C1 = ( N-2 ) * ( WORK( I ) - T*SI )
293: C0 = -(T*SI)*SI + 2*WORK( I )*SI - N*AVG
294: D = C1*C1 - 4*C0*C2
295:
296: IF ( D .LE. 0 ) THEN
297: INFO = -1
298: RETURN
299: END IF
300: SI = -2*C0 / ( C1 + SQRT( D ) )
301:
302: D = SI - S( I )
303: U = ZERO
304: IF ( UP ) THEN
305: DO J = 1, I
306: T = CABS1( A( J, I ) )
307: U = U + S( J )*T
308: WORK( J ) = WORK( J ) + D*T
309: END DO
310: DO J = I+1,N
311: T = CABS1( A( I, J ) )
312: U = U + S( J )*T
313: WORK( J ) = WORK( J ) + D*T
314: END DO
315: ELSE
316: DO J = 1, I
317: T = CABS1( A( I, J ) )
318: U = U + S( J )*T
319: WORK( J ) = WORK( J ) + D*T
320: END DO
321: DO J = I+1,N
322: T = CABS1( A( J, I ) )
323: U = U + S( J )*T
324: WORK( J ) = WORK( J ) + D*T
325: END DO
326: END IF
327: AVG = AVG + ( U + WORK( I ) ) * D / N
328: S( I ) = SI
329: END DO
330: END DO
331:
332: 999 CONTINUE
333:
334: SMLNUM = DLAMCH( 'SAFEMIN' )
335: BIGNUM = ONE / SMLNUM
336: SMIN = BIGNUM
337: SMAX = ZERO
338: T = ONE / SQRT( AVG )
339: BASE = DLAMCH( 'B' )
340: U = ONE / LOG( BASE )
341: DO I = 1, N
342: S( I ) = BASE ** INT( U * LOG( S( I ) * T ) )
343: SMIN = MIN( SMIN, S( I ) )
344: SMAX = MAX( SMAX, S( I ) )
345: END DO
346: SCOND = MAX( SMIN, SMLNUM ) / MIN( SMAX, BIGNUM )
347: *
348: END
CVSweb interface <joel.bertrand@systella.fr>