1: *> \brief \b ZTREVC3
2: *
3: * =========== DOCUMENTATION ===========
4: *
5: * Online html documentation available at
6: * http://www.netlib.org/lapack/explore-html/
7: *
8: *> \htmlonly
9: *> Download ZTREVC3 + dependencies
10: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ztrevc3.f">
11: *> [TGZ]</a>
12: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ztrevc3.f">
13: *> [ZIP]</a>
14: *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ztrevc3.f">
15: *> [TXT]</a>
16: *> \endhtmlonly
17: *
18: * Definition:
19: * ===========
20: *
21: * SUBROUTINE ZTREVC3( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL,
22: * VR, LDVR, MM, M, WORK, LWORK, RWORK, INFO )
23: *
24: * .. Scalar Arguments ..
25: * CHARACTER HOWMNY, SIDE
26: * INTEGER INFO, LDT, LDVL, LDVR, LWORK, M, MM, N
27: * ..
28: * .. Array Arguments ..
29: * LOGICAL SELECT( * )
30: * DOUBLE PRECISION RWORK( * )
31: * COMPLEX*16 T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),
32: * $ WORK( * )
33: * ..
34: *
35: *
36: *> \par Purpose:
37: * =============
38: *>
39: *> \verbatim
40: *>
41: *> ZTREVC3 computes some or all of the right and/or left eigenvectors of
42: *> a complex upper triangular matrix T.
43: *> Matrices of this type are produced by the Schur factorization of
44: *> a complex general matrix: A = Q*T*Q**H, as computed by ZHSEQR.
45: *>
46: *> The right eigenvector x and the left eigenvector y of T corresponding
47: *> to an eigenvalue w are defined by:
48: *>
49: *> T*x = w*x, (y**H)*T = w*(y**H)
50: *>
51: *> where y**H denotes the conjugate transpose of the vector y.
52: *> The eigenvalues are not input to this routine, but are read directly
53: *> from the diagonal of T.
54: *>
55: *> This routine returns the matrices X and/or Y of right and left
56: *> eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an
57: *> input matrix. If Q is the unitary factor that reduces a matrix A to
58: *> Schur form T, then Q*X and Q*Y are the matrices of right and left
59: *> eigenvectors of A.
60: *>
61: *> This uses a Level 3 BLAS version of the back transformation.
62: *> \endverbatim
63: *
64: * Arguments:
65: * ==========
66: *
67: *> \param[in] SIDE
68: *> \verbatim
69: *> SIDE is CHARACTER*1
70: *> = 'R': compute right eigenvectors only;
71: *> = 'L': compute left eigenvectors only;
72: *> = 'B': compute both right and left eigenvectors.
73: *> \endverbatim
74: *>
75: *> \param[in] HOWMNY
76: *> \verbatim
77: *> HOWMNY is CHARACTER*1
78: *> = 'A': compute all right and/or left eigenvectors;
79: *> = 'B': compute all right and/or left eigenvectors,
80: *> backtransformed using the matrices supplied in
81: *> VR and/or VL;
82: *> = 'S': compute selected right and/or left eigenvectors,
83: *> as indicated by the logical array SELECT.
84: *> \endverbatim
85: *>
86: *> \param[in] SELECT
87: *> \verbatim
88: *> SELECT is LOGICAL array, dimension (N)
89: *> If HOWMNY = 'S', SELECT specifies the eigenvectors to be
90: *> computed.
91: *> The eigenvector corresponding to the j-th eigenvalue is
92: *> computed if SELECT(j) = .TRUE..
93: *> Not referenced if HOWMNY = 'A' or 'B'.
94: *> \endverbatim
95: *>
96: *> \param[in] N
97: *> \verbatim
98: *> N is INTEGER
99: *> The order of the matrix T. N >= 0.
100: *> \endverbatim
101: *>
102: *> \param[in,out] T
103: *> \verbatim
104: *> T is COMPLEX*16 array, dimension (LDT,N)
105: *> The upper triangular matrix T. T is modified, but restored
106: *> on exit.
107: *> \endverbatim
108: *>
109: *> \param[in] LDT
110: *> \verbatim
111: *> LDT is INTEGER
112: *> The leading dimension of the array T. LDT >= max(1,N).
113: *> \endverbatim
114: *>
115: *> \param[in,out] VL
116: *> \verbatim
117: *> VL is COMPLEX*16 array, dimension (LDVL,MM)
118: *> On entry, if SIDE = 'L' or 'B' and HOWMNY = 'B', VL must
119: *> contain an N-by-N matrix Q (usually the unitary matrix Q of
120: *> Schur vectors returned by ZHSEQR).
121: *> On exit, if SIDE = 'L' or 'B', VL contains:
122: *> if HOWMNY = 'A', the matrix Y of left eigenvectors of T;
123: *> if HOWMNY = 'B', the matrix Q*Y;
124: *> if HOWMNY = 'S', the left eigenvectors of T specified by
125: *> SELECT, stored consecutively in the columns
126: *> of VL, in the same order as their
127: *> eigenvalues.
128: *> Not referenced if SIDE = 'R'.
129: *> \endverbatim
130: *>
131: *> \param[in] LDVL
132: *> \verbatim
133: *> LDVL is INTEGER
134: *> The leading dimension of the array VL.
135: *> LDVL >= 1, and if SIDE = 'L' or 'B', LDVL >= N.
136: *> \endverbatim
137: *>
138: *> \param[in,out] VR
139: *> \verbatim
140: *> VR is COMPLEX*16 array, dimension (LDVR,MM)
141: *> On entry, if SIDE = 'R' or 'B' and HOWMNY = 'B', VR must
142: *> contain an N-by-N matrix Q (usually the unitary matrix Q of
143: *> Schur vectors returned by ZHSEQR).
144: *> On exit, if SIDE = 'R' or 'B', VR contains:
145: *> if HOWMNY = 'A', the matrix X of right eigenvectors of T;
146: *> if HOWMNY = 'B', the matrix Q*X;
147: *> if HOWMNY = 'S', the right eigenvectors of T specified by
148: *> SELECT, stored consecutively in the columns
149: *> of VR, in the same order as their
150: *> eigenvalues.
151: *> Not referenced if SIDE = 'L'.
152: *> \endverbatim
153: *>
154: *> \param[in] LDVR
155: *> \verbatim
156: *> LDVR is INTEGER
157: *> The leading dimension of the array VR.
158: *> LDVR >= 1, and if SIDE = 'R' or 'B', LDVR >= N.
159: *> \endverbatim
160: *>
161: *> \param[in] MM
162: *> \verbatim
163: *> MM is INTEGER
164: *> The number of columns in the arrays VL and/or VR. MM >= M.
165: *> \endverbatim
166: *>
167: *> \param[out] M
168: *> \verbatim
169: *> M is INTEGER
170: *> The number of columns in the arrays VL and/or VR actually
171: *> used to store the eigenvectors.
172: *> If HOWMNY = 'A' or 'B', M is set to N.
173: *> Each selected eigenvector occupies one column.
174: *> \endverbatim
175: *>
176: *> \param[out] WORK
177: *> \verbatim
178: *> WORK is COMPLEX*16 array, dimension (MAX(1,LWORK))
179: *> \endverbatim
180: *>
181: *> \param[in] LWORK
182: *> \verbatim
183: *> LWORK is INTEGER
184: *> The dimension of array WORK. LWORK >= max(1,2*N).
185: *> For optimum performance, LWORK >= N + 2*N*NB, where NB is
186: *> the optimal blocksize.
187: *>
188: *> If LWORK = -1, then a workspace query is assumed; the routine
189: *> only calculates the optimal size of the WORK array, returns
190: *> this value as the first entry of the WORK array, and no error
191: *> message related to LWORK is issued by XERBLA.
192: *> \endverbatim
193: *>
194: *> \param[out] RWORK
195: *> \verbatim
196: *> RWORK is DOUBLE PRECISION array, dimension (LRWORK)
197: *> \endverbatim
198: *>
199: *> \param[in] LRWORK
200: *> \verbatim
201: *> LRWORK is INTEGER
202: *> The dimension of array RWORK. LRWORK >= max(1,N).
203: *>
204: *> If LRWORK = -1, then a workspace query is assumed; the routine
205: *> only calculates the optimal size of the RWORK array, returns
206: *> this value as the first entry of the RWORK array, and no error
207: *> message related to LRWORK is issued by XERBLA.
208: *> \endverbatim
209: *>
210: *> \param[out] INFO
211: *> \verbatim
212: *> INFO is INTEGER
213: *> = 0: successful exit
214: *> < 0: if INFO = -i, the i-th argument had an illegal value
215: *> \endverbatim
216: *
217: * Authors:
218: * ========
219: *
220: *> \author Univ. of Tennessee
221: *> \author Univ. of California Berkeley
222: *> \author Univ. of Colorado Denver
223: *> \author NAG Ltd.
224: *
225: *> \date November 2011
226: *
227: * @precisions fortran z -> c
228: *
229: *> \ingroup complex16OTHERcomputational
230: *
231: *> \par Further Details:
232: * =====================
233: *>
234: *> \verbatim
235: *>
236: *> The algorithm used in this program is basically backward (forward)
237: *> substitution, with scaling to make the the code robust against
238: *> possible overflow.
239: *>
240: *> Each eigenvector is normalized so that the element of largest
241: *> magnitude has magnitude 1; here the magnitude of a complex number
242: *> (x,y) is taken to be |x| + |y|.
243: *> \endverbatim
244: *>
245: * =====================================================================
246: SUBROUTINE ZTREVC3( SIDE, HOWMNY, SELECT, N, T, LDT, VL, LDVL, VR,
247: $ LDVR, MM, M, WORK, LWORK, RWORK, LRWORK, INFO)
248: IMPLICIT NONE
249: *
250: * -- LAPACK computational routine (version 3.4.0) --
251: * -- LAPACK is a software package provided by Univ. of Tennessee, --
252: * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
253: * November 2011
254: *
255: * .. Scalar Arguments ..
256: CHARACTER HOWMNY, SIDE
257: INTEGER INFO, LDT, LDVL, LDVR, LWORK, LRWORK, M, MM, N
258: * ..
259: * .. Array Arguments ..
260: LOGICAL SELECT( * )
261: DOUBLE PRECISION RWORK( * )
262: COMPLEX*16 T( LDT, * ), VL( LDVL, * ), VR( LDVR, * ),
263: $ WORK( * )
264: * ..
265: *
266: * =====================================================================
267: *
268: * .. Parameters ..
269: DOUBLE PRECISION ZERO, ONE
270: PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
271: COMPLEX*16 CZERO, CONE
272: PARAMETER ( CZERO = ( 0.0D+0, 0.0D+0 ),
273: $ CONE = ( 1.0D+0, 0.0D+0 ) )
274: INTEGER NBMIN, NBMAX
275: PARAMETER ( NBMIN = 8, NBMAX = 128 )
276: * ..
277: * .. Local Scalars ..
278: LOGICAL ALLV, BOTHV, LEFTV, LQUERY, OVER, RIGHTV, SOMEV
279: INTEGER I, II, IS, J, K, KI, IV, MAXWRK, NB
280: DOUBLE PRECISION OVFL, REMAX, SCALE, SMIN, SMLNUM, ULP, UNFL
281: COMPLEX*16 CDUM
282: * ..
283: * .. External Functions ..
284: LOGICAL LSAME
285: INTEGER ILAENV, IZAMAX
286: DOUBLE PRECISION DLAMCH, DZASUM
287: EXTERNAL LSAME, ILAENV, IZAMAX, DLAMCH, DZASUM
288: * ..
289: * .. External Subroutines ..
290: EXTERNAL XERBLA, ZCOPY, ZDSCAL, ZGEMV, ZLATRS
291: * ..
292: * .. Intrinsic Functions ..
293: INTRINSIC ABS, DBLE, DCMPLX, CONJG, AIMAG, MAX
294: * ..
295: * .. Statement Functions ..
296: DOUBLE PRECISION CABS1
297: * ..
298: * .. Statement Function definitions ..
299: CABS1( CDUM ) = ABS( DBLE( CDUM ) ) + ABS( AIMAG( CDUM ) )
300: * ..
301: * .. Executable Statements ..
302: *
303: * Decode and test the input parameters
304: *
305: BOTHV = LSAME( SIDE, 'B' )
306: RIGHTV = LSAME( SIDE, 'R' ) .OR. BOTHV
307: LEFTV = LSAME( SIDE, 'L' ) .OR. BOTHV
308: *
309: ALLV = LSAME( HOWMNY, 'A' )
310: OVER = LSAME( HOWMNY, 'B' )
311: SOMEV = LSAME( HOWMNY, 'S' )
312: *
313: * Set M to the number of columns required to store the selected
314: * eigenvectors.
315: *
316: IF( SOMEV ) THEN
317: M = 0
318: DO 10 J = 1, N
319: IF( SELECT( J ) )
320: $ M = M + 1
321: 10 CONTINUE
322: ELSE
323: M = N
324: END IF
325: *
326: INFO = 0
327: NB = ILAENV( 1, 'ZTREVC', SIDE // HOWMNY, N, -1, -1, -1 )
328: MAXWRK = N + 2*N*NB
329: WORK(1) = MAXWRK
330: RWORK(1) = N
331: LQUERY = ( LWORK.EQ.-1 .OR. LRWORK.EQ.-1 )
332: IF( .NOT.RIGHTV .AND. .NOT.LEFTV ) THEN
333: INFO = -1
334: ELSE IF( .NOT.ALLV .AND. .NOT.OVER .AND. .NOT.SOMEV ) THEN
335: INFO = -2
336: ELSE IF( N.LT.0 ) THEN
337: INFO = -4
338: ELSE IF( LDT.LT.MAX( 1, N ) ) THEN
339: INFO = -6
340: ELSE IF( LDVL.LT.1 .OR. ( LEFTV .AND. LDVL.LT.N ) ) THEN
341: INFO = -8
342: ELSE IF( LDVR.LT.1 .OR. ( RIGHTV .AND. LDVR.LT.N ) ) THEN
343: INFO = -10
344: ELSE IF( MM.LT.M ) THEN
345: INFO = -11
346: ELSE IF( LWORK.LT.MAX( 1, 2*N ) .AND. .NOT.LQUERY ) THEN
347: INFO = -14
348: ELSE IF ( LRWORK.LT.MAX( 1, N ) .AND. .NOT.LQUERY ) THEN
349: INFO = -16
350: END IF
351: IF( INFO.NE.0 ) THEN
352: CALL XERBLA( 'ZTREVC3', -INFO )
353: RETURN
354: ELSE IF( LQUERY ) THEN
355: RETURN
356: END IF
357: *
358: * Quick return if possible.
359: *
360: IF( N.EQ.0 )
361: $ RETURN
362: *
363: * Use blocked version of back-transformation if sufficient workspace.
364: * Zero-out the workspace to avoid potential NaN propagation.
365: *
366: IF( OVER .AND. LWORK .GE. N + 2*N*NBMIN ) THEN
367: NB = (LWORK - N) / (2*N)
368: NB = MIN( NB, NBMAX )
369: CALL ZLASET( 'F', N, 1+2*NB, CZERO, CZERO, WORK, N )
370: ELSE
371: NB = 1
372: END IF
373: *
374: * Set the constants to control overflow.
375: *
376: UNFL = DLAMCH( 'Safe minimum' )
377: OVFL = ONE / UNFL
378: CALL DLABAD( UNFL, OVFL )
379: ULP = DLAMCH( 'Precision' )
380: SMLNUM = UNFL*( N / ULP )
381: *
382: * Store the diagonal elements of T in working array WORK.
383: *
384: DO 20 I = 1, N
385: WORK( I ) = T( I, I )
386: 20 CONTINUE
387: *
388: * Compute 1-norm of each column of strictly upper triangular
389: * part of T to control overflow in triangular solver.
390: *
391: RWORK( 1 ) = ZERO
392: DO 30 J = 2, N
393: RWORK( J ) = DZASUM( J-1, T( 1, J ), 1 )
394: 30 CONTINUE
395: *
396: IF( RIGHTV ) THEN
397: *
398: * ============================================================
399: * Compute right eigenvectors.
400: *
401: * IV is index of column in current block.
402: * Non-blocked version always uses IV=NB=1;
403: * blocked version starts with IV=NB, goes down to 1.
404: * (Note the "0-th" column is used to store the original diagonal.)
405: IV = NB
406: IS = M
407: DO 80 KI = N, 1, -1
408: IF( SOMEV ) THEN
409: IF( .NOT.SELECT( KI ) )
410: $ GO TO 80
411: END IF
412: SMIN = MAX( ULP*( CABS1( T( KI, KI ) ) ), SMLNUM )
413: *
414: * --------------------------------------------------------
415: * Complex right eigenvector
416: *
417: WORK( KI + IV*N ) = CONE
418: *
419: * Form right-hand side.
420: *
421: DO 40 K = 1, KI - 1
422: WORK( K + IV*N ) = -T( K, KI )
423: 40 CONTINUE
424: *
425: * Solve upper triangular system:
426: * [ T(1:KI-1,1:KI-1) - T(KI,KI) ]*X = SCALE*WORK.
427: *
428: DO 50 K = 1, KI - 1
429: T( K, K ) = T( K, K ) - T( KI, KI )
430: IF( CABS1( T( K, K ) ).LT.SMIN )
431: $ T( K, K ) = SMIN
432: 50 CONTINUE
433: *
434: IF( KI.GT.1 ) THEN
435: CALL ZLATRS( 'Upper', 'No transpose', 'Non-unit', 'Y',
436: $ KI-1, T, LDT, WORK( 1 + IV*N ), SCALE,
437: $ RWORK, INFO )
438: WORK( KI + IV*N ) = SCALE
439: END IF
440: *
441: * Copy the vector x or Q*x to VR and normalize.
442: *
443: IF( .NOT.OVER ) THEN
444: * ------------------------------
445: * no back-transform: copy x to VR and normalize.
446: CALL ZCOPY( KI, WORK( 1 + IV*N ), 1, VR( 1, IS ), 1 )
447: *
448: II = IZAMAX( KI, VR( 1, IS ), 1 )
449: REMAX = ONE / CABS1( VR( II, IS ) )
450: CALL ZDSCAL( KI, REMAX, VR( 1, IS ), 1 )
451: *
452: DO 60 K = KI + 1, N
453: VR( K, IS ) = CZERO
454: 60 CONTINUE
455: *
456: ELSE IF( NB.EQ.1 ) THEN
457: * ------------------------------
458: * version 1: back-transform each vector with GEMV, Q*x.
459: IF( KI.GT.1 )
460: $ CALL ZGEMV( 'N', N, KI-1, CONE, VR, LDVR,
461: $ WORK( 1 + IV*N ), 1, DCMPLX( SCALE ),
462: $ VR( 1, KI ), 1 )
463: *
464: II = IZAMAX( N, VR( 1, KI ), 1 )
465: REMAX = ONE / CABS1( VR( II, KI ) )
466: CALL ZDSCAL( N, REMAX, VR( 1, KI ), 1 )
467: *
468: ELSE
469: * ------------------------------
470: * version 2: back-transform block of vectors with GEMM
471: * zero out below vector
472: DO K = KI + 1, N
473: WORK( K + IV*N ) = CZERO
474: END DO
475: *
476: * Columns IV:NB of work are valid vectors.
477: * When the number of vectors stored reaches NB,
478: * or if this was last vector, do the GEMM
479: IF( (IV.EQ.1) .OR. (KI.EQ.1) ) THEN
480: CALL ZGEMM( 'N', 'N', N, NB-IV+1, KI+NB-IV, CONE,
481: $ VR, LDVR,
482: $ WORK( 1 + (IV)*N ), N,
483: $ CZERO,
484: $ WORK( 1 + (NB+IV)*N ), N )
485: * normalize vectors
486: DO K = IV, NB
487: II = IZAMAX( N, WORK( 1 + (NB+K)*N ), 1 )
488: REMAX = ONE / CABS1( WORK( II + (NB+K)*N ) )
489: CALL ZDSCAL( N, REMAX, WORK( 1 + (NB+K)*N ), 1 )
490: END DO
491: CALL ZLACPY( 'F', N, NB-IV+1,
492: $ WORK( 1 + (NB+IV)*N ), N,
493: $ VR( 1, KI ), LDVR )
494: IV = NB
495: ELSE
496: IV = IV - 1
497: END IF
498: END IF
499: *
500: * Restore the original diagonal elements of T.
501: *
502: DO 70 K = 1, KI - 1
503: T( K, K ) = WORK( K )
504: 70 CONTINUE
505: *
506: IS = IS - 1
507: 80 CONTINUE
508: END IF
509: *
510: IF( LEFTV ) THEN
511: *
512: * ============================================================
513: * Compute left eigenvectors.
514: *
515: * IV is index of column in current block.
516: * Non-blocked version always uses IV=1;
517: * blocked version starts with IV=1, goes up to NB.
518: * (Note the "0-th" column is used to store the original diagonal.)
519: IV = 1
520: IS = 1
521: DO 130 KI = 1, N
522: *
523: IF( SOMEV ) THEN
524: IF( .NOT.SELECT( KI ) )
525: $ GO TO 130
526: END IF
527: SMIN = MAX( ULP*( CABS1( T( KI, KI ) ) ), SMLNUM )
528: *
529: * --------------------------------------------------------
530: * Complex left eigenvector
531: *
532: WORK( KI + IV*N ) = CONE
533: *
534: * Form right-hand side.
535: *
536: DO 90 K = KI + 1, N
537: WORK( K + IV*N ) = -CONJG( T( KI, K ) )
538: 90 CONTINUE
539: *
540: * Solve conjugate-transposed triangular system:
541: * [ T(KI+1:N,KI+1:N) - T(KI,KI) ]**H * X = SCALE*WORK.
542: *
543: DO 100 K = KI + 1, N
544: T( K, K ) = T( K, K ) - T( KI, KI )
545: IF( CABS1( T( K, K ) ).LT.SMIN )
546: $ T( K, K ) = SMIN
547: 100 CONTINUE
548: *
549: IF( KI.LT.N ) THEN
550: CALL ZLATRS( 'Upper', 'Conjugate transpose', 'Non-unit',
551: $ 'Y', N-KI, T( KI+1, KI+1 ), LDT,
552: $ WORK( KI+1 + IV*N ), SCALE, RWORK, INFO )
553: WORK( KI + IV*N ) = SCALE
554: END IF
555: *
556: * Copy the vector x or Q*x to VL and normalize.
557: *
558: IF( .NOT.OVER ) THEN
559: * ------------------------------
560: * no back-transform: copy x to VL and normalize.
561: CALL ZCOPY( N-KI+1, WORK( KI + IV*N ), 1, VL(KI,IS), 1 )
562: *
563: II = IZAMAX( N-KI+1, VL( KI, IS ), 1 ) + KI - 1
564: REMAX = ONE / CABS1( VL( II, IS ) )
565: CALL ZDSCAL( N-KI+1, REMAX, VL( KI, IS ), 1 )
566: *
567: DO 110 K = 1, KI - 1
568: VL( K, IS ) = CZERO
569: 110 CONTINUE
570: *
571: ELSE IF( NB.EQ.1 ) THEN
572: * ------------------------------
573: * version 1: back-transform each vector with GEMV, Q*x.
574: IF( KI.LT.N )
575: $ CALL ZGEMV( 'N', N, N-KI, CONE, VL( 1, KI+1 ), LDVL,
576: $ WORK( KI+1 + IV*N ), 1, DCMPLX( SCALE ),
577: $ VL( 1, KI ), 1 )
578: *
579: II = IZAMAX( N, VL( 1, KI ), 1 )
580: REMAX = ONE / CABS1( VL( II, KI ) )
581: CALL ZDSCAL( N, REMAX, VL( 1, KI ), 1 )
582: *
583: ELSE
584: * ------------------------------
585: * version 2: back-transform block of vectors with GEMM
586: * zero out above vector
587: * could go from KI-NV+1 to KI-1
588: DO K = 1, KI - 1
589: WORK( K + IV*N ) = CZERO
590: END DO
591: *
592: * Columns 1:IV of work are valid vectors.
593: * When the number of vectors stored reaches NB,
594: * or if this was last vector, do the GEMM
595: IF( (IV.EQ.NB) .OR. (KI.EQ.N) ) THEN
596: CALL ZGEMM( 'N', 'N', N, IV, N-KI+IV, ONE,
597: $ VL( 1, KI-IV+1 ), LDVL,
598: $ WORK( KI-IV+1 + (1)*N ), N,
599: $ CZERO,
600: $ WORK( 1 + (NB+1)*N ), N )
601: * normalize vectors
602: DO K = 1, IV
603: II = IZAMAX( N, WORK( 1 + (NB+K)*N ), 1 )
604: REMAX = ONE / CABS1( WORK( II + (NB+K)*N ) )
605: CALL ZDSCAL( N, REMAX, WORK( 1 + (NB+K)*N ), 1 )
606: END DO
607: CALL ZLACPY( 'F', N, IV,
608: $ WORK( 1 + (NB+1)*N ), N,
609: $ VL( 1, KI-IV+1 ), LDVL )
610: IV = 1
611: ELSE
612: IV = IV + 1
613: END IF
614: END IF
615: *
616: * Restore the original diagonal elements of T.
617: *
618: DO 120 K = KI + 1, N
619: T( K, K ) = WORK( K )
620: 120 CONTINUE
621: *
622: IS = IS + 1
623: 130 CONTINUE
624: END IF
625: *
626: RETURN
627: *
628: * End of ZTREVC3
629: *
630: END
CVSweb interface <joel.bertrand@systella.fr>