1: *> \brief \b DTGEVC
2: *
3: * =========== DOCUMENTATION ===========
4: *
5: * Online html documentation available at
6: * http://www.netlib.org/lapack/explore-html/
7: *
8: *> \htmlonly
9: *> Download DTGEVC + dependencies
10: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dtgevc.f">
11: *> [TGZ]</a>
12: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dtgevc.f">
13: *> [ZIP]</a>
14: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dtgevc.f">
15: *> [TXT]</a>
16: *> \endhtmlonly
17: *
18: * Definition:
19: * ===========
20: *
21: * SUBROUTINE DTGEVC( SIDE, HOWMNY, SELECT, N, S, LDS, P, LDP, VL,
22: * LDVL, VR, LDVR, MM, M, WORK, INFO )
23: *
24: * .. Scalar Arguments ..
25: * CHARACTER HOWMNY, SIDE
26: * INTEGER INFO, LDP, LDS, LDVL, LDVR, M, MM, N
27: * ..
28: * .. Array Arguments ..
29: * LOGICAL SELECT( * )
30: * DOUBLE PRECISION P( LDP, * ), S( LDS, * ), VL( LDVL, * ),
31: * $ VR( LDVR, * ), WORK( * )
32: * ..
33: *
34: *
35: *
36: *> \par Purpose:
37: * =============
38: *>
39: *> \verbatim
40: *>
41: *> DTGEVC computes some or all of the right and/or left eigenvectors of
42: *> a pair of real matrices (S,P), where S is a quasi-triangular matrix
43: *> and P is upper triangular. Matrix pairs of this type are produced by
44: *> the generalized Schur factorization of a matrix pair (A,B):
45: *>
46: *> A = Q*S*Z**T, B = Q*P*Z**T
47: *>
48: *> as computed by DGGHRD + DHGEQZ.
49: *>
50: *> The right eigenvector x and the left eigenvector y of (S,P)
51: *> corresponding to an eigenvalue w are defined by:
52: *>
53: *> S*x = w*P*x, (y**H)*S = w*(y**H)*P,
54: *>
55: *> where y**H denotes the conjugate tranpose of y.
56: *> The eigenvalues are not input to this routine, but are computed
57: *> directly from the diagonal blocks of S and P.
58: *>
59: *> This routine returns the matrices X and/or Y of right and left
60: *> eigenvectors of (S,P), or the products Z*X and/or Q*Y,
61: *> where Z and Q are input matrices.
62: *> If Q and Z are the orthogonal factors from the generalized Schur
63: *> factorization of a matrix pair (A,B), then Z*X and Q*Y
64: *> are the matrices of right and left eigenvectors of (A,B).
65: *>
66: *> \endverbatim
67: *
68: * Arguments:
69: * ==========
70: *
71: *> \param[in] SIDE
72: *> \verbatim
73: *> SIDE is CHARACTER*1
74: *> = 'R': compute right eigenvectors only;
75: *> = 'L': compute left eigenvectors only;
76: *> = 'B': compute both right and left eigenvectors.
77: *> \endverbatim
78: *>
79: *> \param[in] HOWMNY
80: *> \verbatim
81: *> HOWMNY is CHARACTER*1
82: *> = 'A': compute all right and/or left eigenvectors;
83: *> = 'B': compute all right and/or left eigenvectors,
84: *> backtransformed by the matrices in VR and/or VL;
85: *> = 'S': compute selected right and/or left eigenvectors,
86: *> specified by the logical array SELECT.
87: *> \endverbatim
88: *>
89: *> \param[in] SELECT
90: *> \verbatim
91: *> SELECT is LOGICAL array, dimension (N)
92: *> If HOWMNY='S', SELECT specifies the eigenvectors to be
93: *> computed. If w(j) is a real eigenvalue, the corresponding
94: *> real eigenvector is computed if SELECT(j) is .TRUE..
95: *> If w(j) and w(j+1) are the real and imaginary parts of a
96: *> complex eigenvalue, the corresponding complex eigenvector
97: *> is computed if either SELECT(j) or SELECT(j+1) is .TRUE.,
98: *> and on exit SELECT(j) is set to .TRUE. and SELECT(j+1) is
99: *> set to .FALSE..
100: *> Not referenced if HOWMNY = 'A' or 'B'.
101: *> \endverbatim
102: *>
103: *> \param[in] N
104: *> \verbatim
105: *> N is INTEGER
106: *> The order of the matrices S and P. N >= 0.
107: *> \endverbatim
108: *>
109: *> \param[in] S
110: *> \verbatim
111: *> S is DOUBLE PRECISION array, dimension (LDS,N)
112: *> The upper quasi-triangular matrix S from a generalized Schur
113: *> factorization, as computed by DHGEQZ.
114: *> \endverbatim
115: *>
116: *> \param[in] LDS
117: *> \verbatim
118: *> LDS is INTEGER
119: *> The leading dimension of array S. LDS >= max(1,N).
120: *> \endverbatim
121: *>
122: *> \param[in] P
123: *> \verbatim
124: *> P is DOUBLE PRECISION array, dimension (LDP,N)
125: *> The upper triangular matrix P from a generalized Schur
126: *> factorization, as computed by DHGEQZ.
127: *> 2-by-2 diagonal blocks of P corresponding to 2-by-2 blocks
128: *> of S must be in positive diagonal form.
129: *> \endverbatim
130: *>
131: *> \param[in] LDP
132: *> \verbatim
133: *> LDP is INTEGER
134: *> The leading dimension of array P. LDP >= max(1,N).
135: *> \endverbatim
136: *>
137: *> \param[in,out] VL
138: *> \verbatim
139: *> VL is DOUBLE PRECISION array, dimension (LDVL,MM)
140: *> On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must
141: *> contain an N-by-N matrix Q (usually the orthogonal matrix Q
142: *> of left Schur vectors returned by DHGEQZ).
143: *> On exit, if SIDE = 'L' or 'B', VL contains:
144: *> if HOWMNY = 'A', the matrix Y of left eigenvectors of (S,P);
145: *> if HOWMNY = 'B', the matrix Q*Y;
146: *> if HOWMNY = 'S', the left eigenvectors of (S,P) specified by
147: *> SELECT, stored consecutively in the columns of
148: *> VL, in the same order as their eigenvalues.
149: *>
150: *> A complex eigenvector corresponding to a complex eigenvalue
151: *> is stored in two consecutive columns, the first holding the
152: *> real part, and the second the imaginary part.
153: *>
154: *> Not referenced if SIDE = 'R'.
155: *> \endverbatim
156: *>
157: *> \param[in] LDVL
158: *> \verbatim
159: *> LDVL is INTEGER
160: *> The leading dimension of array VL. LDVL >= 1, and if
161: *> SIDE = 'L' or 'B', LDVL >= N.
162: *> \endverbatim
163: *>
164: *> \param[in,out] VR
165: *> \verbatim
166: *> VR is DOUBLE PRECISION array, dimension (LDVR,MM)
167: *> On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must
168: *> contain an N-by-N matrix Z (usually the orthogonal matrix Z
169: *> of right Schur vectors returned by DHGEQZ).
170: *>
171: *> On exit, if SIDE = 'R' or 'B', VR contains:
172: *> if HOWMNY = 'A', the matrix X of right eigenvectors of (S,P);
173: *> if HOWMNY = 'B' or 'b', the matrix Z*X;
174: *> if HOWMNY = 'S' or 's', the right eigenvectors of (S,P)
175: *> specified by SELECT, stored consecutively in the
176: *> columns of VR, in the same order as their
177: *> eigenvalues.
178: *>
179: *> A complex eigenvector corresponding to a complex eigenvalue
180: *> is stored in two consecutive columns, the first holding the
181: *> real part and the second the imaginary part.
182: *>
183: *> Not referenced if SIDE = 'L'.
184: *> \endverbatim
185: *>
186: *> \param[in] LDVR
187: *> \verbatim
188: *> LDVR is INTEGER
189: *> The leading dimension of the array VR. LDVR >= 1, and if
190: *> SIDE = 'R' or 'B', LDVR >= N.
191: *> \endverbatim
192: *>
193: *> \param[in] MM
194: *> \verbatim
195: *> MM is INTEGER
196: *> The number of columns in the arrays VL and/or VR. MM >= M.
197: *> \endverbatim
198: *>
199: *> \param[out] M
200: *> \verbatim
201: *> M is INTEGER
202: *> The number of columns in the arrays VL and/or VR actually
203: *> used to store the eigenvectors. If HOWMNY = 'A' or 'B', M
204: *> is set to N. Each selected real eigenvector occupies one
205: *> column and each selected complex eigenvector occupies two
206: *> columns.
207: *> \endverbatim
208: *>
209: *> \param[out] WORK
210: *> \verbatim
211: *> WORK is DOUBLE PRECISION array, dimension (6*N)
212: *> \endverbatim
213: *>
214: *> \param[out] INFO
215: *> \verbatim
216: *> INFO is INTEGER
217: *> = 0: successful exit.
218: *> < 0: if INFO = -i, the i-th argument had an illegal value.
219: *> > 0: the 2-by-2 block (INFO:INFO+1) does not have a complex
220: *> eigenvalue.
221: *> \endverbatim
222: *
223: * Authors:
224: * ========
225: *
226: *> \author Univ. of Tennessee
227: *> \author Univ. of California Berkeley
228: *> \author Univ. of Colorado Denver
229: *> \author NAG Ltd.
230: *
231: *> \date November 2011
232: *
233: *> \ingroup doubleGEcomputational
234: *
235: *> \par Further Details:
236: * =====================
237: *>
238: *> \verbatim
239: *>
240: *> Allocation of workspace:
241: *> ---------- -- ---------
242: *>
243: *> WORK( j ) = 1-norm of j-th column of A, above the diagonal
244: *> WORK( N+j ) = 1-norm of j-th column of B, above the diagonal
245: *> WORK( 2*N+1:3*N ) = real part of eigenvector
246: *> WORK( 3*N+1:4*N ) = imaginary part of eigenvector
247: *> WORK( 4*N+1:5*N ) = real part of back-transformed eigenvector
248: *> WORK( 5*N+1:6*N ) = imaginary part of back-transformed eigenvector
249: *>
250: *> Rowwise vs. columnwise solution methods:
251: *> ------- -- ---------- -------- -------
252: *>
253: *> Finding a generalized eigenvector consists basically of solving the
254: *> singular triangular system
255: *>
256: *> (A - w B) x = 0 (for right) or: (A - w B)**H y = 0 (for left)
257: *>
258: *> Consider finding the i-th right eigenvector (assume all eigenvalues
259: *> are real). The equation to be solved is:
260: *> n i
261: *> 0 = sum C(j,k) v(k) = sum C(j,k) v(k) for j = i,. . .,1
262: *> k=j k=j
263: *>
264: *> where C = (A - w B) (The components v(i+1:n) are 0.)
265: *>
266: *> The "rowwise" method is:
267: *>
268: *> (1) v(i) := 1
269: *> for j = i-1,. . .,1:
270: *> i
271: *> (2) compute s = - sum C(j,k) v(k) and
272: *> k=j+1
273: *>
274: *> (3) v(j) := s / C(j,j)
275: *>
276: *> Step 2 is sometimes called the "dot product" step, since it is an
277: *> inner product between the j-th row and the portion of the eigenvector
278: *> that has been computed so far.
279: *>
280: *> The "columnwise" method consists basically in doing the sums
281: *> for all the rows in parallel. As each v(j) is computed, the
282: *> contribution of v(j) times the j-th column of C is added to the
283: *> partial sums. Since FORTRAN arrays are stored columnwise, this has
284: *> the advantage that at each step, the elements of C that are accessed
285: *> are adjacent to one another, whereas with the rowwise method, the
286: *> elements accessed at a step are spaced LDS (and LDP) words apart.
287: *>
288: *> When finding left eigenvectors, the matrix in question is the
289: *> transpose of the one in storage, so the rowwise method then
290: *> actually accesses columns of A and B at each step, and so is the
291: *> preferred method.
292: *> \endverbatim
293: *>
294: * =====================================================================
295: SUBROUTINE DTGEVC( SIDE, HOWMNY, SELECT, N, S, LDS, P, LDP, VL,
296: $ LDVL, VR, LDVR, MM, M, WORK, INFO )
297: *
298: * -- LAPACK computational routine (version 3.4.0) --
299: * -- LAPACK is a software package provided by Univ. of Tennessee, --
300: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
301: * November 2011
302: *
303: * .. Scalar Arguments ..
304: CHARACTER HOWMNY, SIDE
305: INTEGER INFO, LDP, LDS, LDVL, LDVR, M, MM, N
306: * ..
307: * .. Array Arguments ..
308: LOGICAL SELECT( * )
309: DOUBLE PRECISION P( LDP, * ), S( LDS, * ), VL( LDVL, * ),
310: $ VR( LDVR, * ), WORK( * )
311: * ..
312: *
313: *
314: * =====================================================================
315: *
316: * .. Parameters ..
317: DOUBLE PRECISION ZERO, ONE, SAFETY
318: PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0,
319: $ SAFETY = 1.0D+2 )
320: * ..
321: * .. Local Scalars ..
322: LOGICAL COMPL, COMPR, IL2BY2, ILABAD, ILALL, ILBACK,
323: $ ILBBAD, ILCOMP, ILCPLX, LSA, LSB
324: INTEGER I, IBEG, IEIG, IEND, IHWMNY, IINFO, IM, ISIDE,
325: $ J, JA, JC, JE, JR, JW, NA, NW
326: DOUBLE PRECISION ACOEF, ACOEFA, ANORM, ASCALE, BCOEFA, BCOEFI,
327: $ BCOEFR, BIG, BIGNUM, BNORM, BSCALE, CIM2A,
328: $ CIM2B, CIMAGA, CIMAGB, CRE2A, CRE2B, CREALA,
329: $ CREALB, DMIN, SAFMIN, SALFAR, SBETA, SCALE,
330: $ SMALL, TEMP, TEMP2, TEMP2I, TEMP2R, ULP, XMAX,
331: $ XSCALE
332: * ..
333: * .. Local Arrays ..
334: DOUBLE PRECISION BDIAG( 2 ), SUM( 2, 2 ), SUMS( 2, 2 ),
335: $ SUMP( 2, 2 )
336: * ..
337: * .. External Functions ..
338: LOGICAL LSAME
339: DOUBLE PRECISION DLAMCH
340: EXTERNAL LSAME, DLAMCH
341: * ..
342: * .. External Subroutines ..
343: EXTERNAL DGEMV, DLABAD, DLACPY, DLAG2, DLALN2, XERBLA
344: * ..
345: * .. Intrinsic Functions ..
346: INTRINSIC ABS, MAX, MIN
347: * ..
348: * .. Executable Statements ..
349: *
350: * Decode and Test the input parameters
351: *
352: IF( LSAME( HOWMNY, 'A' ) ) THEN
353: IHWMNY = 1
354: ILALL = .TRUE.
355: ILBACK = .FALSE.
356: ELSE IF( LSAME( HOWMNY, 'S' ) ) THEN
357: IHWMNY = 2
358: ILALL = .FALSE.
359: ILBACK = .FALSE.
360: ELSE IF( LSAME( HOWMNY, 'B' ) ) THEN
361: IHWMNY = 3
362: ILALL = .TRUE.
363: ILBACK = .TRUE.
364: ELSE
365: IHWMNY = -1
366: ILALL = .TRUE.
367: END IF
368: *
369: IF( LSAME( SIDE, 'R' ) ) THEN
370: ISIDE = 1
371: COMPL = .FALSE.
372: COMPR = .TRUE.
373: ELSE IF( LSAME( SIDE, 'L' ) ) THEN
374: ISIDE = 2
375: COMPL = .TRUE.
376: COMPR = .FALSE.
377: ELSE IF( LSAME( SIDE, 'B' ) ) THEN
378: ISIDE = 3
379: COMPL = .TRUE.
380: COMPR = .TRUE.
381: ELSE
382: ISIDE = -1
383: END IF
384: *
385: INFO = 0
386: IF( ISIDE.LT.0 ) THEN
387: INFO = -1
388: ELSE IF( IHWMNY.LT.0 ) THEN
389: INFO = -2
390: ELSE IF( N.LT.0 ) THEN
391: INFO = -4
392: ELSE IF( LDS.LT.MAX( 1, N ) ) THEN
393: INFO = -6
394: ELSE IF( LDP.LT.MAX( 1, N ) ) THEN
395: INFO = -8
396: END IF
397: IF( INFO.NE.0 ) THEN
398: CALL XERBLA( 'DTGEVC', -INFO )
399: RETURN
400: END IF
401: *
402: * Count the number of eigenvectors to be computed
403: *
404: IF( .NOT.ILALL ) THEN
405: IM = 0
406: ILCPLX = .FALSE.
407: DO 10 J = 1, N
408: IF( ILCPLX ) THEN
409: ILCPLX = .FALSE.
410: GO TO 10
411: END IF
412: IF( J.LT.N ) THEN
413: IF( S( J+1, J ).NE.ZERO )
414: $ ILCPLX = .TRUE.
415: END IF
416: IF( ILCPLX ) THEN
417: IF( SELECT( J ) .OR. SELECT( J+1 ) )
418: $ IM = IM + 2
419: ELSE
420: IF( SELECT( J ) )
421: $ IM = IM + 1
422: END IF
423: 10 CONTINUE
424: ELSE
425: IM = N
426: END IF
427: *
428: * Check 2-by-2 diagonal blocks of A, B
429: *
430: ILABAD = .FALSE.
431: ILBBAD = .FALSE.
432: DO 20 J = 1, N - 1
433: IF( S( J+1, J ).NE.ZERO ) THEN
434: IF( P( J, J ).EQ.ZERO .OR. P( J+1, J+1 ).EQ.ZERO .OR.
435: $ P( J, J+1 ).NE.ZERO )ILBBAD = .TRUE.
436: IF( J.LT.N-1 ) THEN
437: IF( S( J+2, J+1 ).NE.ZERO )
438: $ ILABAD = .TRUE.
439: END IF
440: END IF
441: 20 CONTINUE
442: *
443: IF( ILABAD ) THEN
444: INFO = -5
445: ELSE IF( ILBBAD ) THEN
446: INFO = -7
447: ELSE IF( COMPL .AND. LDVL.LT.N .OR. LDVL.LT.1 ) THEN
448: INFO = -10
449: ELSE IF( COMPR .AND. LDVR.LT.N .OR. LDVR.LT.1 ) THEN
450: INFO = -12
451: ELSE IF( MM.LT.IM ) THEN
452: INFO = -13
453: END IF
454: IF( INFO.NE.0 ) THEN
455: CALL XERBLA( 'DTGEVC', -INFO )
456: RETURN
457: END IF
458: *
459: * Quick return if possible
460: *
461: M = IM
462: IF( N.EQ.0 )
463: $ RETURN
464: *
465: * Machine Constants
466: *
467: SAFMIN = DLAMCH( 'Safe minimum' )
468: BIG = ONE / SAFMIN
469: CALL DLABAD( SAFMIN, BIG )
470: ULP = DLAMCH( 'Epsilon' )*DLAMCH( 'Base' )
471: SMALL = SAFMIN*N / ULP
472: BIG = ONE / SMALL
473: BIGNUM = ONE / ( SAFMIN*N )
474: *
475: * Compute the 1-norm of each column of the strictly upper triangular
476: * part (i.e., excluding all elements belonging to the diagonal
477: * blocks) of A and B to check for possible overflow in the
478: * triangular solver.
479: *
480: ANORM = ABS( S( 1, 1 ) )
481: IF( N.GT.1 )
482: $ ANORM = ANORM + ABS( S( 2, 1 ) )
483: BNORM = ABS( P( 1, 1 ) )
484: WORK( 1 ) = ZERO
485: WORK( N+1 ) = ZERO
486: *
487: DO 50 J = 2, N
488: TEMP = ZERO
489: TEMP2 = ZERO
490: IF( S( J, J-1 ).EQ.ZERO ) THEN
491: IEND = J - 1
492: ELSE
493: IEND = J - 2
494: END IF
495: DO 30 I = 1, IEND
496: TEMP = TEMP + ABS( S( I, J ) )
497: TEMP2 = TEMP2 + ABS( P( I, J ) )
498: 30 CONTINUE
499: WORK( J ) = TEMP
500: WORK( N+J ) = TEMP2
501: DO 40 I = IEND + 1, MIN( J+1, N )
502: TEMP = TEMP + ABS( S( I, J ) )
503: TEMP2 = TEMP2 + ABS( P( I, J ) )
504: 40 CONTINUE
505: ANORM = MAX( ANORM, TEMP )
506: BNORM = MAX( BNORM, TEMP2 )
507: 50 CONTINUE
508: *
509: ASCALE = ONE / MAX( ANORM, SAFMIN )
510: BSCALE = ONE / MAX( BNORM, SAFMIN )
511: *
512: * Left eigenvectors
513: *
514: IF( COMPL ) THEN
515: IEIG = 0
516: *
517: * Main loop over eigenvalues
518: *
519: ILCPLX = .FALSE.
520: DO 220 JE = 1, N
521: *
522: * Skip this iteration if (a) HOWMNY='S' and SELECT=.FALSE., or
523: * (b) this would be the second of a complex pair.
524: * Check for complex eigenvalue, so as to be sure of which
525: * entry(-ies) of SELECT to look at.
526: *
527: IF( ILCPLX ) THEN
528: ILCPLX = .FALSE.
529: GO TO 220
530: END IF
531: NW = 1
532: IF( JE.LT.N ) THEN
533: IF( S( JE+1, JE ).NE.ZERO ) THEN
534: ILCPLX = .TRUE.
535: NW = 2
536: END IF
537: END IF
538: IF( ILALL ) THEN
539: ILCOMP = .TRUE.
540: ELSE IF( ILCPLX ) THEN
541: ILCOMP = SELECT( JE ) .OR. SELECT( JE+1 )
542: ELSE
543: ILCOMP = SELECT( JE )
544: END IF
545: IF( .NOT.ILCOMP )
546: $ GO TO 220
547: *
548: * Decide if (a) singular pencil, (b) real eigenvalue, or
549: * (c) complex eigenvalue.
550: *
551: IF( .NOT.ILCPLX ) THEN
552: IF( ABS( S( JE, JE ) ).LE.SAFMIN .AND.
553: $ ABS( P( JE, JE ) ).LE.SAFMIN ) THEN
554: *
555: * Singular matrix pencil -- return unit eigenvector
556: *
557: IEIG = IEIG + 1
558: DO 60 JR = 1, N
559: VL( JR, IEIG ) = ZERO
560: 60 CONTINUE
561: VL( IEIG, IEIG ) = ONE
562: GO TO 220
563: END IF
564: END IF
565: *
566: * Clear vector
567: *
568: DO 70 JR = 1, NW*N
569: WORK( 2*N+JR ) = ZERO
570: 70 CONTINUE
571: * T
572: * Compute coefficients in ( a A - b B ) y = 0
573: * a is ACOEF
574: * b is BCOEFR + i*BCOEFI
575: *
576: IF( .NOT.ILCPLX ) THEN
577: *
578: * Real eigenvalue
579: *
580: TEMP = ONE / MAX( ABS( S( JE, JE ) )*ASCALE,
581: $ ABS( P( JE, JE ) )*BSCALE, SAFMIN )
582: SALFAR = ( TEMP*S( JE, JE ) )*ASCALE
583: SBETA = ( TEMP*P( JE, JE ) )*BSCALE
584: ACOEF = SBETA*ASCALE
585: BCOEFR = SALFAR*BSCALE
586: BCOEFI = ZERO
587: *
588: * Scale to avoid underflow
589: *
590: SCALE = ONE
591: LSA = ABS( SBETA ).GE.SAFMIN .AND. ABS( ACOEF ).LT.SMALL
592: LSB = ABS( SALFAR ).GE.SAFMIN .AND. ABS( BCOEFR ).LT.
593: $ SMALL
594: IF( LSA )
595: $ SCALE = ( SMALL / ABS( SBETA ) )*MIN( ANORM, BIG )
596: IF( LSB )
597: $ SCALE = MAX( SCALE, ( SMALL / ABS( SALFAR ) )*
598: $ MIN( BNORM, BIG ) )
599: IF( LSA .OR. LSB ) THEN
600: SCALE = MIN( SCALE, ONE /
601: $ ( SAFMIN*MAX( ONE, ABS( ACOEF ),
602: $ ABS( BCOEFR ) ) ) )
603: IF( LSA ) THEN
604: ACOEF = ASCALE*( SCALE*SBETA )
605: ELSE
606: ACOEF = SCALE*ACOEF
607: END IF
608: IF( LSB ) THEN
609: BCOEFR = BSCALE*( SCALE*SALFAR )
610: ELSE
611: BCOEFR = SCALE*BCOEFR
612: END IF
613: END IF
614: ACOEFA = ABS( ACOEF )
615: BCOEFA = ABS( BCOEFR )
616: *
617: * First component is 1
618: *
619: WORK( 2*N+JE ) = ONE
620: XMAX = ONE
621: ELSE
622: *
623: * Complex eigenvalue
624: *
625: CALL DLAG2( S( JE, JE ), LDS, P( JE, JE ), LDP,
626: $ SAFMIN*SAFETY, ACOEF, TEMP, BCOEFR, TEMP2,
627: $ BCOEFI )
628: BCOEFI = -BCOEFI
629: IF( BCOEFI.EQ.ZERO ) THEN
630: INFO = JE
631: RETURN
632: END IF
633: *
634: * Scale to avoid over/underflow
635: *
636: ACOEFA = ABS( ACOEF )
637: BCOEFA = ABS( BCOEFR ) + ABS( BCOEFI )
638: SCALE = ONE
639: IF( ACOEFA*ULP.LT.SAFMIN .AND. ACOEFA.GE.SAFMIN )
640: $ SCALE = ( SAFMIN / ULP ) / ACOEFA
641: IF( BCOEFA*ULP.LT.SAFMIN .AND. BCOEFA.GE.SAFMIN )
642: $ SCALE = MAX( SCALE, ( SAFMIN / ULP ) / BCOEFA )
643: IF( SAFMIN*ACOEFA.GT.ASCALE )
644: $ SCALE = ASCALE / ( SAFMIN*ACOEFA )
645: IF( SAFMIN*BCOEFA.GT.BSCALE )
646: $ SCALE = MIN( SCALE, BSCALE / ( SAFMIN*BCOEFA ) )
647: IF( SCALE.NE.ONE ) THEN
648: ACOEF = SCALE*ACOEF
649: ACOEFA = ABS( ACOEF )
650: BCOEFR = SCALE*BCOEFR
651: BCOEFI = SCALE*BCOEFI
652: BCOEFA = ABS( BCOEFR ) + ABS( BCOEFI )
653: END IF
654: *
655: * Compute first two components of eigenvector
656: *
657: TEMP = ACOEF*S( JE+1, JE )
658: TEMP2R = ACOEF*S( JE, JE ) - BCOEFR*P( JE, JE )
659: TEMP2I = -BCOEFI*P( JE, JE )
660: IF( ABS( TEMP ).GT.ABS( TEMP2R )+ABS( TEMP2I ) ) THEN
661: WORK( 2*N+JE ) = ONE
662: WORK( 3*N+JE ) = ZERO
663: WORK( 2*N+JE+1 ) = -TEMP2R / TEMP
664: WORK( 3*N+JE+1 ) = -TEMP2I / TEMP
665: ELSE
666: WORK( 2*N+JE+1 ) = ONE
667: WORK( 3*N+JE+1 ) = ZERO
668: TEMP = ACOEF*S( JE, JE+1 )
669: WORK( 2*N+JE ) = ( BCOEFR*P( JE+1, JE+1 )-ACOEF*
670: $ S( JE+1, JE+1 ) ) / TEMP
671: WORK( 3*N+JE ) = BCOEFI*P( JE+1, JE+1 ) / TEMP
672: END IF
673: XMAX = MAX( ABS( WORK( 2*N+JE ) )+ABS( WORK( 3*N+JE ) ),
674: $ ABS( WORK( 2*N+JE+1 ) )+ABS( WORK( 3*N+JE+1 ) ) )
675: END IF
676: *
677: DMIN = MAX( ULP*ACOEFA*ANORM, ULP*BCOEFA*BNORM, SAFMIN )
678: *
679: * T
680: * Triangular solve of (a A - b B) y = 0
681: *
682: * T
683: * (rowwise in (a A - b B) , or columnwise in (a A - b B) )
684: *
685: IL2BY2 = .FALSE.
686: *
687: DO 160 J = JE + NW, N
688: IF( IL2BY2 ) THEN
689: IL2BY2 = .FALSE.
690: GO TO 160
691: END IF
692: *
693: NA = 1
694: BDIAG( 1 ) = P( J, J )
695: IF( J.LT.N ) THEN
696: IF( S( J+1, J ).NE.ZERO ) THEN
697: IL2BY2 = .TRUE.
698: BDIAG( 2 ) = P( J+1, J+1 )
699: NA = 2
700: END IF
701: END IF
702: *
703: * Check whether scaling is necessary for dot products
704: *
705: XSCALE = ONE / MAX( ONE, XMAX )
706: TEMP = MAX( WORK( J ), WORK( N+J ),
707: $ ACOEFA*WORK( J )+BCOEFA*WORK( N+J ) )
708: IF( IL2BY2 )
709: $ TEMP = MAX( TEMP, WORK( J+1 ), WORK( N+J+1 ),
710: $ ACOEFA*WORK( J+1 )+BCOEFA*WORK( N+J+1 ) )
711: IF( TEMP.GT.BIGNUM*XSCALE ) THEN
712: DO 90 JW = 0, NW - 1
713: DO 80 JR = JE, J - 1
714: WORK( ( JW+2 )*N+JR ) = XSCALE*
715: $ WORK( ( JW+2 )*N+JR )
716: 80 CONTINUE
717: 90 CONTINUE
718: XMAX = XMAX*XSCALE
719: END IF
720: *
721: * Compute dot products
722: *
723: * j-1
724: * SUM = sum conjg( a*S(k,j) - b*P(k,j) )*x(k)
725: * k=je
726: *
727: * To reduce the op count, this is done as
728: *
729: * _ j-1 _ j-1
730: * a*conjg( sum S(k,j)*x(k) ) - b*conjg( sum P(k,j)*x(k) )
731: * k=je k=je
732: *
733: * which may cause underflow problems if A or B are close
734: * to underflow. (E.g., less than SMALL.)
735: *
736: *
737: DO 120 JW = 1, NW
738: DO 110 JA = 1, NA
739: SUMS( JA, JW ) = ZERO
740: SUMP( JA, JW ) = ZERO
741: *
742: DO 100 JR = JE, J - 1
743: SUMS( JA, JW ) = SUMS( JA, JW ) +
744: $ S( JR, J+JA-1 )*
745: $ WORK( ( JW+1 )*N+JR )
746: SUMP( JA, JW ) = SUMP( JA, JW ) +
747: $ P( JR, J+JA-1 )*
748: $ WORK( ( JW+1 )*N+JR )
749: 100 CONTINUE
750: 110 CONTINUE
751: 120 CONTINUE
752: *
753: DO 130 JA = 1, NA
754: IF( ILCPLX ) THEN
755: SUM( JA, 1 ) = -ACOEF*SUMS( JA, 1 ) +
756: $ BCOEFR*SUMP( JA, 1 ) -
757: $ BCOEFI*SUMP( JA, 2 )
758: SUM( JA, 2 ) = -ACOEF*SUMS( JA, 2 ) +
759: $ BCOEFR*SUMP( JA, 2 ) +
760: $ BCOEFI*SUMP( JA, 1 )
761: ELSE
762: SUM( JA, 1 ) = -ACOEF*SUMS( JA, 1 ) +
763: $ BCOEFR*SUMP( JA, 1 )
764: END IF
765: 130 CONTINUE
766: *
767: * T
768: * Solve ( a A - b B ) y = SUM(,)
769: * with scaling and perturbation of the denominator
770: *
771: CALL DLALN2( .TRUE., NA, NW, DMIN, ACOEF, S( J, J ), LDS,
772: $ BDIAG( 1 ), BDIAG( 2 ), SUM, 2, BCOEFR,
773: $ BCOEFI, WORK( 2*N+J ), N, SCALE, TEMP,
774: $ IINFO )
775: IF( SCALE.LT.ONE ) THEN
776: DO 150 JW = 0, NW - 1
777: DO 140 JR = JE, J - 1
778: WORK( ( JW+2 )*N+JR ) = SCALE*
779: $ WORK( ( JW+2 )*N+JR )
780: 140 CONTINUE
781: 150 CONTINUE
782: XMAX = SCALE*XMAX
783: END IF
784: XMAX = MAX( XMAX, TEMP )
785: 160 CONTINUE
786: *
787: * Copy eigenvector to VL, back transforming if
788: * HOWMNY='B'.
789: *
790: IEIG = IEIG + 1
791: IF( ILBACK ) THEN
792: DO 170 JW = 0, NW - 1
793: CALL DGEMV( 'N', N, N+1-JE, ONE, VL( 1, JE ), LDVL,
794: $ WORK( ( JW+2 )*N+JE ), 1, ZERO,
795: $ WORK( ( JW+4 )*N+1 ), 1 )
796: 170 CONTINUE
797: CALL DLACPY( ' ', N, NW, WORK( 4*N+1 ), N, VL( 1, JE ),
798: $ LDVL )
799: IBEG = 1
800: ELSE
801: CALL DLACPY( ' ', N, NW, WORK( 2*N+1 ), N, VL( 1, IEIG ),
802: $ LDVL )
803: IBEG = JE
804: END IF
805: *
806: * Scale eigenvector
807: *
808: XMAX = ZERO
809: IF( ILCPLX ) THEN
810: DO 180 J = IBEG, N
811: XMAX = MAX( XMAX, ABS( VL( J, IEIG ) )+
812: $ ABS( VL( J, IEIG+1 ) ) )
813: 180 CONTINUE
814: ELSE
815: DO 190 J = IBEG, N
816: XMAX = MAX( XMAX, ABS( VL( J, IEIG ) ) )
817: 190 CONTINUE
818: END IF
819: *
820: IF( XMAX.GT.SAFMIN ) THEN
821: XSCALE = ONE / XMAX
822: *
823: DO 210 JW = 0, NW - 1
824: DO 200 JR = IBEG, N
825: VL( JR, IEIG+JW ) = XSCALE*VL( JR, IEIG+JW )
826: 200 CONTINUE
827: 210 CONTINUE
828: END IF
829: IEIG = IEIG + NW - 1
830: *
831: 220 CONTINUE
832: END IF
833: *
834: * Right eigenvectors
835: *
836: IF( COMPR ) THEN
837: IEIG = IM + 1
838: *
839: * Main loop over eigenvalues
840: *
841: ILCPLX = .FALSE.
842: DO 500 JE = N, 1, -1
843: *
844: * Skip this iteration if (a) HOWMNY='S' and SELECT=.FALSE., or
845: * (b) this would be the second of a complex pair.
846: * Check for complex eigenvalue, so as to be sure of which
847: * entry(-ies) of SELECT to look at -- if complex, SELECT(JE)
848: * or SELECT(JE-1).
849: * If this is a complex pair, the 2-by-2 diagonal block
850: * corresponding to the eigenvalue is in rows/columns JE-1:JE
851: *
852: IF( ILCPLX ) THEN
853: ILCPLX = .FALSE.
854: GO TO 500
855: END IF
856: NW = 1
857: IF( JE.GT.1 ) THEN
858: IF( S( JE, JE-1 ).NE.ZERO ) THEN
859: ILCPLX = .TRUE.
860: NW = 2
861: END IF
862: END IF
863: IF( ILALL ) THEN
864: ILCOMP = .TRUE.
865: ELSE IF( ILCPLX ) THEN
866: ILCOMP = SELECT( JE ) .OR. SELECT( JE-1 )
867: ELSE
868: ILCOMP = SELECT( JE )
869: END IF
870: IF( .NOT.ILCOMP )
871: $ GO TO 500
872: *
873: * Decide if (a) singular pencil, (b) real eigenvalue, or
874: * (c) complex eigenvalue.
875: *
876: IF( .NOT.ILCPLX ) THEN
877: IF( ABS( S( JE, JE ) ).LE.SAFMIN .AND.
878: $ ABS( P( JE, JE ) ).LE.SAFMIN ) THEN
879: *
880: * Singular matrix pencil -- unit eigenvector
881: *
882: IEIG = IEIG - 1
883: DO 230 JR = 1, N
884: VR( JR, IEIG ) = ZERO
885: 230 CONTINUE
886: VR( IEIG, IEIG ) = ONE
887: GO TO 500
888: END IF
889: END IF
890: *
891: * Clear vector
892: *
893: DO 250 JW = 0, NW - 1
894: DO 240 JR = 1, N
895: WORK( ( JW+2 )*N+JR ) = ZERO
896: 240 CONTINUE
897: 250 CONTINUE
898: *
899: * Compute coefficients in ( a A - b B ) x = 0
900: * a is ACOEF
901: * b is BCOEFR + i*BCOEFI
902: *
903: IF( .NOT.ILCPLX ) THEN
904: *
905: * Real eigenvalue
906: *
907: TEMP = ONE / MAX( ABS( S( JE, JE ) )*ASCALE,
908: $ ABS( P( JE, JE ) )*BSCALE, SAFMIN )
909: SALFAR = ( TEMP*S( JE, JE ) )*ASCALE
910: SBETA = ( TEMP*P( JE, JE ) )*BSCALE
911: ACOEF = SBETA*ASCALE
912: BCOEFR = SALFAR*BSCALE
913: BCOEFI = ZERO
914: *
915: * Scale to avoid underflow
916: *
917: SCALE = ONE
918: LSA = ABS( SBETA ).GE.SAFMIN .AND. ABS( ACOEF ).LT.SMALL
919: LSB = ABS( SALFAR ).GE.SAFMIN .AND. ABS( BCOEFR ).LT.
920: $ SMALL
921: IF( LSA )
922: $ SCALE = ( SMALL / ABS( SBETA ) )*MIN( ANORM, BIG )
923: IF( LSB )
924: $ SCALE = MAX( SCALE, ( SMALL / ABS( SALFAR ) )*
925: $ MIN( BNORM, BIG ) )
926: IF( LSA .OR. LSB ) THEN
927: SCALE = MIN( SCALE, ONE /
928: $ ( SAFMIN*MAX( ONE, ABS( ACOEF ),
929: $ ABS( BCOEFR ) ) ) )
930: IF( LSA ) THEN
931: ACOEF = ASCALE*( SCALE*SBETA )
932: ELSE
933: ACOEF = SCALE*ACOEF
934: END IF
935: IF( LSB ) THEN
936: BCOEFR = BSCALE*( SCALE*SALFAR )
937: ELSE
938: BCOEFR = SCALE*BCOEFR
939: END IF
940: END IF
941: ACOEFA = ABS( ACOEF )
942: BCOEFA = ABS( BCOEFR )
943: *
944: * First component is 1
945: *
946: WORK( 2*N+JE ) = ONE
947: XMAX = ONE
948: *
949: * Compute contribution from column JE of A and B to sum
950: * (See "Further Details", above.)
951: *
952: DO 260 JR = 1, JE - 1
953: WORK( 2*N+JR ) = BCOEFR*P( JR, JE ) -
954: $ ACOEF*S( JR, JE )
955: 260 CONTINUE
956: ELSE
957: *
958: * Complex eigenvalue
959: *
960: CALL DLAG2( S( JE-1, JE-1 ), LDS, P( JE-1, JE-1 ), LDP,
961: $ SAFMIN*SAFETY, ACOEF, TEMP, BCOEFR, TEMP2,
962: $ BCOEFI )
963: IF( BCOEFI.EQ.ZERO ) THEN
964: INFO = JE - 1
965: RETURN
966: END IF
967: *
968: * Scale to avoid over/underflow
969: *
970: ACOEFA = ABS( ACOEF )
971: BCOEFA = ABS( BCOEFR ) + ABS( BCOEFI )
972: SCALE = ONE
973: IF( ACOEFA*ULP.LT.SAFMIN .AND. ACOEFA.GE.SAFMIN )
974: $ SCALE = ( SAFMIN / ULP ) / ACOEFA
975: IF( BCOEFA*ULP.LT.SAFMIN .AND. BCOEFA.GE.SAFMIN )
976: $ SCALE = MAX( SCALE, ( SAFMIN / ULP ) / BCOEFA )
977: IF( SAFMIN*ACOEFA.GT.ASCALE )
978: $ SCALE = ASCALE / ( SAFMIN*ACOEFA )
979: IF( SAFMIN*BCOEFA.GT.BSCALE )
980: $ SCALE = MIN( SCALE, BSCALE / ( SAFMIN*BCOEFA ) )
981: IF( SCALE.NE.ONE ) THEN
982: ACOEF = SCALE*ACOEF
983: ACOEFA = ABS( ACOEF )
984: BCOEFR = SCALE*BCOEFR
985: BCOEFI = SCALE*BCOEFI
986: BCOEFA = ABS( BCOEFR ) + ABS( BCOEFI )
987: END IF
988: *
989: * Compute first two components of eigenvector
990: * and contribution to sums
991: *
992: TEMP = ACOEF*S( JE, JE-1 )
993: TEMP2R = ACOEF*S( JE, JE ) - BCOEFR*P( JE, JE )
994: TEMP2I = -BCOEFI*P( JE, JE )
995: IF( ABS( TEMP ).GE.ABS( TEMP2R )+ABS( TEMP2I ) ) THEN
996: WORK( 2*N+JE ) = ONE
997: WORK( 3*N+JE ) = ZERO
998: WORK( 2*N+JE-1 ) = -TEMP2R / TEMP
999: WORK( 3*N+JE-1 ) = -TEMP2I / TEMP
1000: ELSE
1001: WORK( 2*N+JE-1 ) = ONE
1002: WORK( 3*N+JE-1 ) = ZERO
1003: TEMP = ACOEF*S( JE-1, JE )
1004: WORK( 2*N+JE ) = ( BCOEFR*P( JE-1, JE-1 )-ACOEF*
1005: $ S( JE-1, JE-1 ) ) / TEMP
1006: WORK( 3*N+JE ) = BCOEFI*P( JE-1, JE-1 ) / TEMP
1007: END IF
1008: *
1009: XMAX = MAX( ABS( WORK( 2*N+JE ) )+ABS( WORK( 3*N+JE ) ),
1010: $ ABS( WORK( 2*N+JE-1 ) )+ABS( WORK( 3*N+JE-1 ) ) )
1011: *
1012: * Compute contribution from columns JE and JE-1
1013: * of A and B to the sums.
1014: *
1015: CREALA = ACOEF*WORK( 2*N+JE-1 )
1016: CIMAGA = ACOEF*WORK( 3*N+JE-1 )
1017: CREALB = BCOEFR*WORK( 2*N+JE-1 ) -
1018: $ BCOEFI*WORK( 3*N+JE-1 )
1019: CIMAGB = BCOEFI*WORK( 2*N+JE-1 ) +
1020: $ BCOEFR*WORK( 3*N+JE-1 )
1021: CRE2A = ACOEF*WORK( 2*N+JE )
1022: CIM2A = ACOEF*WORK( 3*N+JE )
1023: CRE2B = BCOEFR*WORK( 2*N+JE ) - BCOEFI*WORK( 3*N+JE )
1024: CIM2B = BCOEFI*WORK( 2*N+JE ) + BCOEFR*WORK( 3*N+JE )
1025: DO 270 JR = 1, JE - 2
1026: WORK( 2*N+JR ) = -CREALA*S( JR, JE-1 ) +
1027: $ CREALB*P( JR, JE-1 ) -
1028: $ CRE2A*S( JR, JE ) + CRE2B*P( JR, JE )
1029: WORK( 3*N+JR ) = -CIMAGA*S( JR, JE-1 ) +
1030: $ CIMAGB*P( JR, JE-1 ) -
1031: $ CIM2A*S( JR, JE ) + CIM2B*P( JR, JE )
1032: 270 CONTINUE
1033: END IF
1034: *
1035: DMIN = MAX( ULP*ACOEFA*ANORM, ULP*BCOEFA*BNORM, SAFMIN )
1036: *
1037: * Columnwise triangular solve of (a A - b B) x = 0
1038: *
1039: IL2BY2 = .FALSE.
1040: DO 370 J = JE - NW, 1, -1
1041: *
1042: * If a 2-by-2 block, is in position j-1:j, wait until
1043: * next iteration to process it (when it will be j:j+1)
1044: *
1045: IF( .NOT.IL2BY2 .AND. J.GT.1 ) THEN
1046: IF( S( J, J-1 ).NE.ZERO ) THEN
1047: IL2BY2 = .TRUE.
1048: GO TO 370
1049: END IF
1050: END IF
1051: BDIAG( 1 ) = P( J, J )
1052: IF( IL2BY2 ) THEN
1053: NA = 2
1054: BDIAG( 2 ) = P( J+1, J+1 )
1055: ELSE
1056: NA = 1
1057: END IF
1058: *
1059: * Compute x(j) (and x(j+1), if 2-by-2 block)
1060: *
1061: CALL DLALN2( .FALSE., NA, NW, DMIN, ACOEF, S( J, J ),
1062: $ LDS, BDIAG( 1 ), BDIAG( 2 ), WORK( 2*N+J ),
1063: $ N, BCOEFR, BCOEFI, SUM, 2, SCALE, TEMP,
1064: $ IINFO )
1065: IF( SCALE.LT.ONE ) THEN
1066: *
1067: DO 290 JW = 0, NW - 1
1068: DO 280 JR = 1, JE
1069: WORK( ( JW+2 )*N+JR ) = SCALE*
1070: $ WORK( ( JW+2 )*N+JR )
1071: 280 CONTINUE
1072: 290 CONTINUE
1073: END IF
1074: XMAX = MAX( SCALE*XMAX, TEMP )
1075: *
1076: DO 310 JW = 1, NW
1077: DO 300 JA = 1, NA
1078: WORK( ( JW+1 )*N+J+JA-1 ) = SUM( JA, JW )
1079: 300 CONTINUE
1080: 310 CONTINUE
1081: *
1082: * w = w + x(j)*(a S(*,j) - b P(*,j) ) with scaling
1083: *
1084: IF( J.GT.1 ) THEN
1085: *
1086: * Check whether scaling is necessary for sum.
1087: *
1088: XSCALE = ONE / MAX( ONE, XMAX )
1089: TEMP = ACOEFA*WORK( J ) + BCOEFA*WORK( N+J )
1090: IF( IL2BY2 )
1091: $ TEMP = MAX( TEMP, ACOEFA*WORK( J+1 )+BCOEFA*
1092: $ WORK( N+J+1 ) )
1093: TEMP = MAX( TEMP, ACOEFA, BCOEFA )
1094: IF( TEMP.GT.BIGNUM*XSCALE ) THEN
1095: *
1096: DO 330 JW = 0, NW - 1
1097: DO 320 JR = 1, JE
1098: WORK( ( JW+2 )*N+JR ) = XSCALE*
1099: $ WORK( ( JW+2 )*N+JR )
1100: 320 CONTINUE
1101: 330 CONTINUE
1102: XMAX = XMAX*XSCALE
1103: END IF
1104: *
1105: * Compute the contributions of the off-diagonals of
1106: * column j (and j+1, if 2-by-2 block) of A and B to the
1107: * sums.
1108: *
1109: *
1110: DO 360 JA = 1, NA
1111: IF( ILCPLX ) THEN
1112: CREALA = ACOEF*WORK( 2*N+J+JA-1 )
1113: CIMAGA = ACOEF*WORK( 3*N+J+JA-1 )
1114: CREALB = BCOEFR*WORK( 2*N+J+JA-1 ) -
1115: $ BCOEFI*WORK( 3*N+J+JA-1 )
1116: CIMAGB = BCOEFI*WORK( 2*N+J+JA-1 ) +
1117: $ BCOEFR*WORK( 3*N+J+JA-1 )
1118: DO 340 JR = 1, J - 1
1119: WORK( 2*N+JR ) = WORK( 2*N+JR ) -
1120: $ CREALA*S( JR, J+JA-1 ) +
1121: $ CREALB*P( JR, J+JA-1 )
1122: WORK( 3*N+JR ) = WORK( 3*N+JR ) -
1123: $ CIMAGA*S( JR, J+JA-1 ) +
1124: $ CIMAGB*P( JR, J+JA-1 )
1125: 340 CONTINUE
1126: ELSE
1127: CREALA = ACOEF*WORK( 2*N+J+JA-1 )
1128: CREALB = BCOEFR*WORK( 2*N+J+JA-1 )
1129: DO 350 JR = 1, J - 1
1130: WORK( 2*N+JR ) = WORK( 2*N+JR ) -
1131: $ CREALA*S( JR, J+JA-1 ) +
1132: $ CREALB*P( JR, J+JA-1 )
1133: 350 CONTINUE
1134: END IF
1135: 360 CONTINUE
1136: END IF
1137: *
1138: IL2BY2 = .FALSE.
1139: 370 CONTINUE
1140: *
1141: * Copy eigenvector to VR, back transforming if
1142: * HOWMNY='B'.
1143: *
1144: IEIG = IEIG - NW
1145: IF( ILBACK ) THEN
1146: *
1147: DO 410 JW = 0, NW - 1
1148: DO 380 JR = 1, N
1149: WORK( ( JW+4 )*N+JR ) = WORK( ( JW+2 )*N+1 )*
1150: $ VR( JR, 1 )
1151: 380 CONTINUE
1152: *
1153: * A series of compiler directives to defeat
1154: * vectorization for the next loop
1155: *
1156: *
1157: DO 400 JC = 2, JE
1158: DO 390 JR = 1, N
1159: WORK( ( JW+4 )*N+JR ) = WORK( ( JW+4 )*N+JR ) +
1160: $ WORK( ( JW+2 )*N+JC )*VR( JR, JC )
1161: 390 CONTINUE
1162: 400 CONTINUE
1163: 410 CONTINUE
1164: *
1165: DO 430 JW = 0, NW - 1
1166: DO 420 JR = 1, N
1167: VR( JR, IEIG+JW ) = WORK( ( JW+4 )*N+JR )
1168: 420 CONTINUE
1169: 430 CONTINUE
1170: *
1171: IEND = N
1172: ELSE
1173: DO 450 JW = 0, NW - 1
1174: DO 440 JR = 1, N
1175: VR( JR, IEIG+JW ) = WORK( ( JW+2 )*N+JR )
1176: 440 CONTINUE
1177: 450 CONTINUE
1178: *
1179: IEND = JE
1180: END IF
1181: *
1182: * Scale eigenvector
1183: *
1184: XMAX = ZERO
1185: IF( ILCPLX ) THEN
1186: DO 460 J = 1, IEND
1187: XMAX = MAX( XMAX, ABS( VR( J, IEIG ) )+
1188: $ ABS( VR( J, IEIG+1 ) ) )
1189: 460 CONTINUE
1190: ELSE
1191: DO 470 J = 1, IEND
1192: XMAX = MAX( XMAX, ABS( VR( J, IEIG ) ) )
1193: 470 CONTINUE
1194: END IF
1195: *
1196: IF( XMAX.GT.SAFMIN ) THEN
1197: XSCALE = ONE / XMAX
1198: DO 490 JW = 0, NW - 1
1199: DO 480 JR = 1, IEND
1200: VR( JR, IEIG+JW ) = XSCALE*VR( JR, IEIG+JW )
1201: 480 CONTINUE
1202: 490 CONTINUE
1203: END IF
1204: 500 CONTINUE
1205: END IF
1206: *
1207: RETURN
1208: *
1209: * End of DTGEVC
1210: *
1211: END
CVSweb interface <joel.bertrand@systella.fr>