File:
[local] /
rpl /
lapack /
lapack /
zggbal.f
Revision
1.7:
download - view:
text,
annotated -
select for diffs -
revision graph
Tue Dec 21 13:53:44 2010 UTC (13 years, 9 months ago) by
bertrand
Branches:
MAIN
CVS tags:
rpl-4_1_3,
rpl-4_1_2,
rpl-4_1_1,
rpl-4_1_0,
rpl-4_0_24,
rpl-4_0_22,
rpl-4_0_21,
rpl-4_0_20,
rpl-4_0,
HEAD
Mise à jour de lapack vers la version 3.3.0.
1: SUBROUTINE ZGGBAL( JOB, N, A, LDA, B, LDB, ILO, IHI, LSCALE,
2: $ RSCALE, WORK, INFO )
3: *
4: * -- LAPACK routine (version 3.2) --
5: * -- LAPACK is a software package provided by Univ. of Tennessee, --
6: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
7: * November 2006
8: *
9: * .. Scalar Arguments ..
10: CHARACTER JOB
11: INTEGER IHI, ILO, INFO, LDA, LDB, N
12: * ..
13: * .. Array Arguments ..
14: DOUBLE PRECISION LSCALE( * ), RSCALE( * ), WORK( * )
15: COMPLEX*16 A( LDA, * ), B( LDB, * )
16: * ..
17: *
18: * Purpose
19: * =======
20: *
21: * ZGGBAL balances a pair of general complex matrices (A,B). This
22: * involves, first, permuting A and B by similarity transformations to
23: * isolate eigenvalues in the first 1 to ILO$-$1 and last IHI+1 to N
24: * elements on the diagonal; and second, applying a diagonal similarity
25: * transformation to rows and columns ILO to IHI to make the rows
26: * and columns as close in norm as possible. Both steps are optional.
27: *
28: * Balancing may reduce the 1-norm of the matrices, and improve the
29: * accuracy of the computed eigenvalues and/or eigenvectors in the
30: * generalized eigenvalue problem A*x = lambda*B*x.
31: *
32: * Arguments
33: * =========
34: *
35: * JOB (input) CHARACTER*1
36: * Specifies the operations to be performed on A and B:
37: * = 'N': none: simply set ILO = 1, IHI = N, LSCALE(I) = 1.0
38: * and RSCALE(I) = 1.0 for i=1,...,N;
39: * = 'P': permute only;
40: * = 'S': scale only;
41: * = 'B': both permute and scale.
42: *
43: * N (input) INTEGER
44: * The order of the matrices A and B. N >= 0.
45: *
46: * A (input/output) COMPLEX*16 array, dimension (LDA,N)
47: * On entry, the input matrix A.
48: * On exit, A is overwritten by the balanced matrix.
49: * If JOB = 'N', A is not referenced.
50: *
51: * LDA (input) INTEGER
52: * The leading dimension of the array A. LDA >= max(1,N).
53: *
54: * B (input/output) COMPLEX*16 array, dimension (LDB,N)
55: * On entry, the input matrix B.
56: * On exit, B is overwritten by the balanced matrix.
57: * If JOB = 'N', B is not referenced.
58: *
59: * LDB (input) INTEGER
60: * The leading dimension of the array B. LDB >= max(1,N).
61: *
62: * ILO (output) INTEGER
63: * IHI (output) INTEGER
64: * ILO and IHI are set to integers such that on exit
65: * A(i,j) = 0 and B(i,j) = 0 if i > j and
66: * j = 1,...,ILO-1 or i = IHI+1,...,N.
67: * If JOB = 'N' or 'S', ILO = 1 and IHI = N.
68: *
69: * LSCALE (output) DOUBLE PRECISION array, dimension (N)
70: * Details of the permutations and scaling factors applied
71: * to the left side of A and B. If P(j) is the index of the
72: * row interchanged with row j, and D(j) is the scaling factor
73: * applied to row j, then
74: * LSCALE(j) = P(j) for J = 1,...,ILO-1
75: * = D(j) for J = ILO,...,IHI
76: * = P(j) for J = IHI+1,...,N.
77: * The order in which the interchanges are made is N to IHI+1,
78: * then 1 to ILO-1.
79: *
80: * RSCALE (output) DOUBLE PRECISION array, dimension (N)
81: * Details of the permutations and scaling factors applied
82: * to the right side of A and B. If P(j) is the index of the
83: * column interchanged with column j, and D(j) is the scaling
84: * factor applied to column j, then
85: * RSCALE(j) = P(j) for J = 1,...,ILO-1
86: * = D(j) for J = ILO,...,IHI
87: * = P(j) for J = IHI+1,...,N.
88: * The order in which the interchanges are made is N to IHI+1,
89: * then 1 to ILO-1.
90: *
91: * WORK (workspace) REAL array, dimension (lwork)
92: * lwork must be at least max(1,6*N) when JOB = 'S' or 'B', and
93: * at least 1 when JOB = 'N' or 'P'.
94: *
95: * INFO (output) INTEGER
96: * = 0: successful exit
97: * < 0: if INFO = -i, the i-th argument had an illegal value.
98: *
99: * Further Details
100: * ===============
101: *
102: * See R.C. WARD, Balancing the generalized eigenvalue problem,
103: * SIAM J. Sci. Stat. Comp. 2 (1981), 141-152.
104: *
105: * =====================================================================
106: *
107: * .. Parameters ..
108: DOUBLE PRECISION ZERO, HALF, ONE
109: PARAMETER ( ZERO = 0.0D+0, HALF = 0.5D+0, ONE = 1.0D+0 )
110: DOUBLE PRECISION THREE, SCLFAC
111: PARAMETER ( THREE = 3.0D+0, SCLFAC = 1.0D+1 )
112: COMPLEX*16 CZERO
113: PARAMETER ( CZERO = ( 0.0D+0, 0.0D+0 ) )
114: * ..
115: * .. Local Scalars ..
116: INTEGER I, ICAB, IFLOW, IP1, IR, IRAB, IT, J, JC, JP1,
117: $ K, KOUNT, L, LCAB, LM1, LRAB, LSFMAX, LSFMIN,
118: $ M, NR, NRP2
119: DOUBLE PRECISION ALPHA, BASL, BETA, CAB, CMAX, COEF, COEF2,
120: $ COEF5, COR, EW, EWC, GAMMA, PGAMMA, RAB, SFMAX,
121: $ SFMIN, SUM, T, TA, TB, TC
122: COMPLEX*16 CDUM
123: * ..
124: * .. External Functions ..
125: LOGICAL LSAME
126: INTEGER IZAMAX
127: DOUBLE PRECISION DDOT, DLAMCH
128: EXTERNAL LSAME, IZAMAX, DDOT, DLAMCH
129: * ..
130: * .. External Subroutines ..
131: EXTERNAL DAXPY, DSCAL, XERBLA, ZDSCAL, ZSWAP
132: * ..
133: * .. Intrinsic Functions ..
134: INTRINSIC ABS, DBLE, DIMAG, INT, LOG10, MAX, MIN, SIGN
135: * ..
136: * .. Statement Functions ..
137: DOUBLE PRECISION CABS1
138: * ..
139: * .. Statement Function definitions ..
140: CABS1( CDUM ) = ABS( DBLE( CDUM ) ) + ABS( DIMAG( CDUM ) )
141: * ..
142: * .. Executable Statements ..
143: *
144: * Test the input parameters
145: *
146: INFO = 0
147: IF( .NOT.LSAME( JOB, 'N' ) .AND. .NOT.LSAME( JOB, 'P' ) .AND.
148: $ .NOT.LSAME( JOB, 'S' ) .AND. .NOT.LSAME( JOB, 'B' ) ) THEN
149: INFO = -1
150: ELSE IF( N.LT.0 ) THEN
151: INFO = -2
152: ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
153: INFO = -4
154: ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
155: INFO = -6
156: END IF
157: IF( INFO.NE.0 ) THEN
158: CALL XERBLA( 'ZGGBAL', -INFO )
159: RETURN
160: END IF
161: *
162: * Quick return if possible
163: *
164: IF( N.EQ.0 ) THEN
165: ILO = 1
166: IHI = N
167: RETURN
168: END IF
169: *
170: IF( N.EQ.1 ) THEN
171: ILO = 1
172: IHI = N
173: LSCALE( 1 ) = ONE
174: RSCALE( 1 ) = ONE
175: RETURN
176: END IF
177: *
178: IF( LSAME( JOB, 'N' ) ) THEN
179: ILO = 1
180: IHI = N
181: DO 10 I = 1, N
182: LSCALE( I ) = ONE
183: RSCALE( I ) = ONE
184: 10 CONTINUE
185: RETURN
186: END IF
187: *
188: K = 1
189: L = N
190: IF( LSAME( JOB, 'S' ) )
191: $ GO TO 190
192: *
193: GO TO 30
194: *
195: * Permute the matrices A and B to isolate the eigenvalues.
196: *
197: * Find row with one nonzero in columns 1 through L
198: *
199: 20 CONTINUE
200: L = LM1
201: IF( L.NE.1 )
202: $ GO TO 30
203: *
204: RSCALE( 1 ) = 1
205: LSCALE( 1 ) = 1
206: GO TO 190
207: *
208: 30 CONTINUE
209: LM1 = L - 1
210: DO 80 I = L, 1, -1
211: DO 40 J = 1, LM1
212: JP1 = J + 1
213: IF( A( I, J ).NE.CZERO .OR. B( I, J ).NE.CZERO )
214: $ GO TO 50
215: 40 CONTINUE
216: J = L
217: GO TO 70
218: *
219: 50 CONTINUE
220: DO 60 J = JP1, L
221: IF( A( I, J ).NE.CZERO .OR. B( I, J ).NE.CZERO )
222: $ GO TO 80
223: 60 CONTINUE
224: J = JP1 - 1
225: *
226: 70 CONTINUE
227: M = L
228: IFLOW = 1
229: GO TO 160
230: 80 CONTINUE
231: GO TO 100
232: *
233: * Find column with one nonzero in rows K through N
234: *
235: 90 CONTINUE
236: K = K + 1
237: *
238: 100 CONTINUE
239: DO 150 J = K, L
240: DO 110 I = K, LM1
241: IP1 = I + 1
242: IF( A( I, J ).NE.CZERO .OR. B( I, J ).NE.CZERO )
243: $ GO TO 120
244: 110 CONTINUE
245: I = L
246: GO TO 140
247: 120 CONTINUE
248: DO 130 I = IP1, L
249: IF( A( I, J ).NE.CZERO .OR. B( I, J ).NE.CZERO )
250: $ GO TO 150
251: 130 CONTINUE
252: I = IP1 - 1
253: 140 CONTINUE
254: M = K
255: IFLOW = 2
256: GO TO 160
257: 150 CONTINUE
258: GO TO 190
259: *
260: * Permute rows M and I
261: *
262: 160 CONTINUE
263: LSCALE( M ) = I
264: IF( I.EQ.M )
265: $ GO TO 170
266: CALL ZSWAP( N-K+1, A( I, K ), LDA, A( M, K ), LDA )
267: CALL ZSWAP( N-K+1, B( I, K ), LDB, B( M, K ), LDB )
268: *
269: * Permute columns M and J
270: *
271: 170 CONTINUE
272: RSCALE( M ) = J
273: IF( J.EQ.M )
274: $ GO TO 180
275: CALL ZSWAP( L, A( 1, J ), 1, A( 1, M ), 1 )
276: CALL ZSWAP( L, B( 1, J ), 1, B( 1, M ), 1 )
277: *
278: 180 CONTINUE
279: GO TO ( 20, 90 )IFLOW
280: *
281: 190 CONTINUE
282: ILO = K
283: IHI = L
284: *
285: IF( LSAME( JOB, 'P' ) ) THEN
286: DO 195 I = ILO, IHI
287: LSCALE( I ) = ONE
288: RSCALE( I ) = ONE
289: 195 CONTINUE
290: RETURN
291: END IF
292: *
293: IF( ILO.EQ.IHI )
294: $ RETURN
295: *
296: * Balance the submatrix in rows ILO to IHI.
297: *
298: NR = IHI - ILO + 1
299: DO 200 I = ILO, IHI
300: RSCALE( I ) = ZERO
301: LSCALE( I ) = ZERO
302: *
303: WORK( I ) = ZERO
304: WORK( I+N ) = ZERO
305: WORK( I+2*N ) = ZERO
306: WORK( I+3*N ) = ZERO
307: WORK( I+4*N ) = ZERO
308: WORK( I+5*N ) = ZERO
309: 200 CONTINUE
310: *
311: * Compute right side vector in resulting linear equations
312: *
313: BASL = LOG10( SCLFAC )
314: DO 240 I = ILO, IHI
315: DO 230 J = ILO, IHI
316: IF( A( I, J ).EQ.CZERO ) THEN
317: TA = ZERO
318: GO TO 210
319: END IF
320: TA = LOG10( CABS1( A( I, J ) ) ) / BASL
321: *
322: 210 CONTINUE
323: IF( B( I, J ).EQ.CZERO ) THEN
324: TB = ZERO
325: GO TO 220
326: END IF
327: TB = LOG10( CABS1( B( I, J ) ) ) / BASL
328: *
329: 220 CONTINUE
330: WORK( I+4*N ) = WORK( I+4*N ) - TA - TB
331: WORK( J+5*N ) = WORK( J+5*N ) - TA - TB
332: 230 CONTINUE
333: 240 CONTINUE
334: *
335: COEF = ONE / DBLE( 2*NR )
336: COEF2 = COEF*COEF
337: COEF5 = HALF*COEF2
338: NRP2 = NR + 2
339: BETA = ZERO
340: IT = 1
341: *
342: * Start generalized conjugate gradient iteration
343: *
344: 250 CONTINUE
345: *
346: GAMMA = DDOT( NR, WORK( ILO+4*N ), 1, WORK( ILO+4*N ), 1 ) +
347: $ DDOT( NR, WORK( ILO+5*N ), 1, WORK( ILO+5*N ), 1 )
348: *
349: EW = ZERO
350: EWC = ZERO
351: DO 260 I = ILO, IHI
352: EW = EW + WORK( I+4*N )
353: EWC = EWC + WORK( I+5*N )
354: 260 CONTINUE
355: *
356: GAMMA = COEF*GAMMA - COEF2*( EW**2+EWC**2 ) - COEF5*( EW-EWC )**2
357: IF( GAMMA.EQ.ZERO )
358: $ GO TO 350
359: IF( IT.NE.1 )
360: $ BETA = GAMMA / PGAMMA
361: T = COEF5*( EWC-THREE*EW )
362: TC = COEF5*( EW-THREE*EWC )
363: *
364: CALL DSCAL( NR, BETA, WORK( ILO ), 1 )
365: CALL DSCAL( NR, BETA, WORK( ILO+N ), 1 )
366: *
367: CALL DAXPY( NR, COEF, WORK( ILO+4*N ), 1, WORK( ILO+N ), 1 )
368: CALL DAXPY( NR, COEF, WORK( ILO+5*N ), 1, WORK( ILO ), 1 )
369: *
370: DO 270 I = ILO, IHI
371: WORK( I ) = WORK( I ) + TC
372: WORK( I+N ) = WORK( I+N ) + T
373: 270 CONTINUE
374: *
375: * Apply matrix to vector
376: *
377: DO 300 I = ILO, IHI
378: KOUNT = 0
379: SUM = ZERO
380: DO 290 J = ILO, IHI
381: IF( A( I, J ).EQ.CZERO )
382: $ GO TO 280
383: KOUNT = KOUNT + 1
384: SUM = SUM + WORK( J )
385: 280 CONTINUE
386: IF( B( I, J ).EQ.CZERO )
387: $ GO TO 290
388: KOUNT = KOUNT + 1
389: SUM = SUM + WORK( J )
390: 290 CONTINUE
391: WORK( I+2*N ) = DBLE( KOUNT )*WORK( I+N ) + SUM
392: 300 CONTINUE
393: *
394: DO 330 J = ILO, IHI
395: KOUNT = 0
396: SUM = ZERO
397: DO 320 I = ILO, IHI
398: IF( A( I, J ).EQ.CZERO )
399: $ GO TO 310
400: KOUNT = KOUNT + 1
401: SUM = SUM + WORK( I+N )
402: 310 CONTINUE
403: IF( B( I, J ).EQ.CZERO )
404: $ GO TO 320
405: KOUNT = KOUNT + 1
406: SUM = SUM + WORK( I+N )
407: 320 CONTINUE
408: WORK( J+3*N ) = DBLE( KOUNT )*WORK( J ) + SUM
409: 330 CONTINUE
410: *
411: SUM = DDOT( NR, WORK( ILO+N ), 1, WORK( ILO+2*N ), 1 ) +
412: $ DDOT( NR, WORK( ILO ), 1, WORK( ILO+3*N ), 1 )
413: ALPHA = GAMMA / SUM
414: *
415: * Determine correction to current iteration
416: *
417: CMAX = ZERO
418: DO 340 I = ILO, IHI
419: COR = ALPHA*WORK( I+N )
420: IF( ABS( COR ).GT.CMAX )
421: $ CMAX = ABS( COR )
422: LSCALE( I ) = LSCALE( I ) + COR
423: COR = ALPHA*WORK( I )
424: IF( ABS( COR ).GT.CMAX )
425: $ CMAX = ABS( COR )
426: RSCALE( I ) = RSCALE( I ) + COR
427: 340 CONTINUE
428: IF( CMAX.LT.HALF )
429: $ GO TO 350
430: *
431: CALL DAXPY( NR, -ALPHA, WORK( ILO+2*N ), 1, WORK( ILO+4*N ), 1 )
432: CALL DAXPY( NR, -ALPHA, WORK( ILO+3*N ), 1, WORK( ILO+5*N ), 1 )
433: *
434: PGAMMA = GAMMA
435: IT = IT + 1
436: IF( IT.LE.NRP2 )
437: $ GO TO 250
438: *
439: * End generalized conjugate gradient iteration
440: *
441: 350 CONTINUE
442: SFMIN = DLAMCH( 'S' )
443: SFMAX = ONE / SFMIN
444: LSFMIN = INT( LOG10( SFMIN ) / BASL+ONE )
445: LSFMAX = INT( LOG10( SFMAX ) / BASL )
446: DO 360 I = ILO, IHI
447: IRAB = IZAMAX( N-ILO+1, A( I, ILO ), LDA )
448: RAB = ABS( A( I, IRAB+ILO-1 ) )
449: IRAB = IZAMAX( N-ILO+1, B( I, ILO ), LDB )
450: RAB = MAX( RAB, ABS( B( I, IRAB+ILO-1 ) ) )
451: LRAB = INT( LOG10( RAB+SFMIN ) / BASL+ONE )
452: IR = LSCALE( I ) + SIGN( HALF, LSCALE( I ) )
453: IR = MIN( MAX( IR, LSFMIN ), LSFMAX, LSFMAX-LRAB )
454: LSCALE( I ) = SCLFAC**IR
455: ICAB = IZAMAX( IHI, A( 1, I ), 1 )
456: CAB = ABS( A( ICAB, I ) )
457: ICAB = IZAMAX( IHI, B( 1, I ), 1 )
458: CAB = MAX( CAB, ABS( B( ICAB, I ) ) )
459: LCAB = INT( LOG10( CAB+SFMIN ) / BASL+ONE )
460: JC = RSCALE( I ) + SIGN( HALF, RSCALE( I ) )
461: JC = MIN( MAX( JC, LSFMIN ), LSFMAX, LSFMAX-LCAB )
462: RSCALE( I ) = SCLFAC**JC
463: 360 CONTINUE
464: *
465: * Row scaling of matrices A and B
466: *
467: DO 370 I = ILO, IHI
468: CALL ZDSCAL( N-ILO+1, LSCALE( I ), A( I, ILO ), LDA )
469: CALL ZDSCAL( N-ILO+1, LSCALE( I ), B( I, ILO ), LDB )
470: 370 CONTINUE
471: *
472: * Column scaling of matrices A and B
473: *
474: DO 380 J = ILO, IHI
475: CALL ZDSCAL( IHI, RSCALE( J ), A( 1, J ), 1 )
476: CALL ZDSCAL( IHI, RSCALE( J ), B( 1, J ), 1 )
477: 380 CONTINUE
478: *
479: RETURN
480: *
481: * End of ZGGBAL
482: *
483: END
CVSweb interface <joel.bertrand@systella.fr>