Lots of trailing whitespaces in the files of Syd. Cleaning this. No big deal.
[platform/upstream/lapack.git] / SRC / zhbgst.f
1 *> \brief \b ZHBGST
2 *
3 *  =========== DOCUMENTATION ===========
4 *
5 * Online html documentation available at
6 *            http://www.netlib.org/lapack/explore-html/
7 *
8 *> \htmlonly
9 *> Download ZHBGST + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zhbgst.f">
11 *> [TGZ]</a>
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zhbgst.f">
13 *> [ZIP]</a>
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zhbgst.f">
15 *> [TXT]</a>
16 *> \endhtmlonly
17 *
18 *  Definition:
19 *  ===========
20 *
21 *       SUBROUTINE ZHBGST( VECT, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, X,
22 *                          LDX, WORK, RWORK, INFO )
23 *
24 *       .. Scalar Arguments ..
25 *       CHARACTER          UPLO, VECT
26 *       INTEGER            INFO, KA, KB, LDAB, LDBB, LDX, N
27 *       ..
28 *       .. Array Arguments ..
29 *       DOUBLE PRECISION   RWORK( * )
30 *       COMPLEX*16         AB( LDAB, * ), BB( LDBB, * ), WORK( * ),
31 *      $                   X( LDX, * )
32 *       ..
33 *
34 *
35 *> \par Purpose:
36 *  =============
37 *>
38 *> \verbatim
39 *>
40 *> ZHBGST reduces a complex Hermitian-definite banded generalized
41 *> eigenproblem  A*x = lambda*B*x  to standard form  C*y = lambda*y,
42 *> such that C has the same bandwidth as A.
43 *>
44 *> B must have been previously factorized as S**H*S by ZPBSTF, using a
45 *> split Cholesky factorization. A is overwritten by C = X**H*A*X, where
46 *> X = S**(-1)*Q and Q is a unitary matrix chosen to preserve the
47 *> bandwidth of A.
48 *> \endverbatim
49 *
50 *  Arguments:
51 *  ==========
52 *
53 *> \param[in] VECT
54 *> \verbatim
55 *>          VECT is CHARACTER*1
56 *>          = 'N':  do not form the transformation matrix X;
57 *>          = 'V':  form X.
58 *> \endverbatim
59 *>
60 *> \param[in] UPLO
61 *> \verbatim
62 *>          UPLO is CHARACTER*1
63 *>          = 'U':  Upper triangle of A is stored;
64 *>          = 'L':  Lower triangle of A is stored.
65 *> \endverbatim
66 *>
67 *> \param[in] N
68 *> \verbatim
69 *>          N is INTEGER
70 *>          The order of the matrices A and B.  N >= 0.
71 *> \endverbatim
72 *>
73 *> \param[in] KA
74 *> \verbatim
75 *>          KA is INTEGER
76 *>          The number of superdiagonals of the matrix A if UPLO = 'U',
77 *>          or the number of subdiagonals if UPLO = 'L'.  KA >= 0.
78 *> \endverbatim
79 *>
80 *> \param[in] KB
81 *> \verbatim
82 *>          KB is INTEGER
83 *>          The number of superdiagonals of the matrix B if UPLO = 'U',
84 *>          or the number of subdiagonals if UPLO = 'L'.  KA >= KB >= 0.
85 *> \endverbatim
86 *>
87 *> \param[in,out] AB
88 *> \verbatim
89 *>          AB is COMPLEX*16 array, dimension (LDAB,N)
90 *>          On entry, the upper or lower triangle of the Hermitian band
91 *>          matrix A, stored in the first ka+1 rows of the array.  The
92 *>          j-th column of A is stored in the j-th column of the array AB
93 *>          as follows:
94 *>          if UPLO = 'U', AB(ka+1+i-j,j) = A(i,j) for max(1,j-ka)<=i<=j;
95 *>          if UPLO = 'L', AB(1+i-j,j)    = A(i,j) for j<=i<=min(n,j+ka).
96 *>
97 *>          On exit, the transformed matrix X**H*A*X, stored in the same
98 *>          format as A.
99 *> \endverbatim
100 *>
101 *> \param[in] LDAB
102 *> \verbatim
103 *>          LDAB is INTEGER
104 *>          The leading dimension of the array AB.  LDAB >= KA+1.
105 *> \endverbatim
106 *>
107 *> \param[in] BB
108 *> \verbatim
109 *>          BB is COMPLEX*16 array, dimension (LDBB,N)
110 *>          The banded factor S from the split Cholesky factorization of
111 *>          B, as returned by ZPBSTF, stored in the first kb+1 rows of
112 *>          the array.
113 *> \endverbatim
114 *>
115 *> \param[in] LDBB
116 *> \verbatim
117 *>          LDBB is INTEGER
118 *>          The leading dimension of the array BB.  LDBB >= KB+1.
119 *> \endverbatim
120 *>
121 *> \param[out] X
122 *> \verbatim
123 *>          X is COMPLEX*16 array, dimension (LDX,N)
124 *>          If VECT = 'V', the n-by-n matrix X.
125 *>          If VECT = 'N', the array X is not referenced.
126 *> \endverbatim
127 *>
128 *> \param[in] LDX
129 *> \verbatim
130 *>          LDX is INTEGER
131 *>          The leading dimension of the array X.
132 *>          LDX >= max(1,N) if VECT = 'V'; LDX >= 1 otherwise.
133 *> \endverbatim
134 *>
135 *> \param[out] WORK
136 *> \verbatim
137 *>          WORK is COMPLEX*16 array, dimension (N)
138 *> \endverbatim
139 *>
140 *> \param[out] RWORK
141 *> \verbatim
142 *>          RWORK is DOUBLE PRECISION array, dimension (N)
143 *> \endverbatim
144 *>
145 *> \param[out] INFO
146 *> \verbatim
147 *>          INFO is INTEGER
148 *>          = 0:  successful exit
149 *>          < 0:  if INFO = -i, the i-th argument had an illegal value.
150 *> \endverbatim
151 *
152 *  Authors:
153 *  ========
154 *
155 *> \author Univ. of Tennessee
156 *> \author Univ. of California Berkeley
157 *> \author Univ. of Colorado Denver
158 *> \author NAG Ltd.
159 *
160 *> \date November 2011
161 *
162 *> \ingroup complex16OTHERcomputational
163 *
164 *  =====================================================================
165       SUBROUTINE ZHBGST( VECT, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, X,
166      $                   LDX, WORK, RWORK, INFO )
167 *
168 *  -- LAPACK computational routine (version 3.4.0) --
169 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
170 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
171 *     November 2011
172 *
173 *     .. Scalar Arguments ..
174       CHARACTER          UPLO, VECT
175       INTEGER            INFO, KA, KB, LDAB, LDBB, LDX, N
176 *     ..
177 *     .. Array Arguments ..
178       DOUBLE PRECISION   RWORK( * )
179       COMPLEX*16         AB( LDAB, * ), BB( LDBB, * ), WORK( * ),
180      $                   X( LDX, * )
181 *     ..
182 *
183 *  =====================================================================
184 *
185 *     .. Parameters ..
186       COMPLEX*16         CZERO, CONE
187       DOUBLE PRECISION   ONE
188       PARAMETER          ( CZERO = ( 0.0D+0, 0.0D+0 ),
189      $                   CONE = ( 1.0D+0, 0.0D+0 ), ONE = 1.0D+0 )
190 *     ..
191 *     .. Local Scalars ..
192       LOGICAL            UPDATE, UPPER, WANTX
193       INTEGER            I, I0, I1, I2, INCA, J, J1, J1T, J2, J2T, K,
194      $                   KA1, KB1, KBT, L, M, NR, NRT, NX
195       DOUBLE PRECISION   BII
196       COMPLEX*16         RA, RA1, T
197 *     ..
198 *     .. External Functions ..
199       LOGICAL            LSAME
200       EXTERNAL           LSAME
201 *     ..
202 *     .. External Subroutines ..
203       EXTERNAL           XERBLA, ZDSCAL, ZGERC, ZGERU, ZLACGV, ZLAR2V,
204      $                   ZLARGV, ZLARTG, ZLARTV, ZLASET, ZROT
205 *     ..
206 *     .. Intrinsic Functions ..
207       INTRINSIC          DBLE, DCONJG, MAX, MIN
208 *     ..
209 *     .. Executable Statements ..
210 *
211 *     Test the input parameters
212 *
213       WANTX = LSAME( VECT, 'V' )
214       UPPER = LSAME( UPLO, 'U' )
215       KA1 = KA + 1
216       KB1 = KB + 1
217       INFO = 0
218       IF( .NOT.WANTX .AND. .NOT.LSAME( VECT, 'N' ) ) THEN
219          INFO = -1
220       ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
221          INFO = -2
222       ELSE IF( N.LT.0 ) THEN
223          INFO = -3
224       ELSE IF( KA.LT.0 ) THEN
225          INFO = -4
226       ELSE IF( KB.LT.0 .OR. KB.GT.KA ) THEN
227          INFO = -5
228       ELSE IF( LDAB.LT.KA+1 ) THEN
229          INFO = -7
230       ELSE IF( LDBB.LT.KB+1 ) THEN
231          INFO = -9
232       ELSE IF( LDX.LT.1 .OR. WANTX .AND. LDX.LT.MAX( 1, N ) ) THEN
233          INFO = -11
234       END IF
235       IF( INFO.NE.0 ) THEN
236          CALL XERBLA( 'ZHBGST', -INFO )
237          RETURN
238       END IF
239 *
240 *     Quick return if possible
241 *
242       IF( N.EQ.0 )
243      $   RETURN
244 *
245       INCA = LDAB*KA1
246 *
247 *     Initialize X to the unit matrix, if needed
248 *
249       IF( WANTX )
250      $   CALL ZLASET( 'Full', N, N, CZERO, CONE, X, LDX )
251 *
252 *     Set M to the splitting point m. It must be the same value as is
253 *     used in ZPBSTF. The chosen value allows the arrays WORK and RWORK
254 *     to be of dimension (N).
255 *
256       M = ( N+KB ) / 2
257 *
258 *     The routine works in two phases, corresponding to the two halves
259 *     of the split Cholesky factorization of B as S**H*S where
260 *
261 *     S = ( U    )
262 *         ( M  L )
263 *
264 *     with U upper triangular of order m, and L lower triangular of
265 *     order n-m. S has the same bandwidth as B.
266 *
267 *     S is treated as a product of elementary matrices:
268 *
269 *     S = S(m)*S(m-1)*...*S(2)*S(1)*S(m+1)*S(m+2)*...*S(n-1)*S(n)
270 *
271 *     where S(i) is determined by the i-th row of S.
272 *
273 *     In phase 1, the index i takes the values n, n-1, ... , m+1;
274 *     in phase 2, it takes the values 1, 2, ... , m.
275 *
276 *     For each value of i, the current matrix A is updated by forming
277 *     inv(S(i))**H*A*inv(S(i)). This creates a triangular bulge outside
278 *     the band of A. The bulge is then pushed down toward the bottom of
279 *     A in phase 1, and up toward the top of A in phase 2, by applying
280 *     plane rotations.
281 *
282 *     There are kb*(kb+1)/2 elements in the bulge, but at most 2*kb-1
283 *     of them are linearly independent, so annihilating a bulge requires
284 *     only 2*kb-1 plane rotations. The rotations are divided into a 1st
285 *     set of kb-1 rotations, and a 2nd set of kb rotations.
286 *
287 *     Wherever possible, rotations are generated and applied in vector
288 *     operations of length NR between the indices J1 and J2 (sometimes
289 *     replaced by modified values NRT, J1T or J2T).
290 *
291 *     The real cosines and complex sines of the rotations are stored in
292 *     the arrays RWORK and WORK, those of the 1st set in elements
293 *     2:m-kb-1, and those of the 2nd set in elements m-kb+1:n.
294 *
295 *     The bulges are not formed explicitly; nonzero elements outside the
296 *     band are created only when they are required for generating new
297 *     rotations; they are stored in the array WORK, in positions where
298 *     they are later overwritten by the sines of the rotations which
299 *     annihilate them.
300 *
301 *     **************************** Phase 1 *****************************
302 *
303 *     The logical structure of this phase is:
304 *
305 *     UPDATE = .TRUE.
306 *     DO I = N, M + 1, -1
307 *        use S(i) to update A and create a new bulge
308 *        apply rotations to push all bulges KA positions downward
309 *     END DO
310 *     UPDATE = .FALSE.
311 *     DO I = M + KA + 1, N - 1
312 *        apply rotations to push all bulges KA positions downward
313 *     END DO
314 *
315 *     To avoid duplicating code, the two loops are merged.
316 *
317       UPDATE = .TRUE.
318       I = N + 1
319    10 CONTINUE
320       IF( UPDATE ) THEN
321          I = I - 1
322          KBT = MIN( KB, I-1 )
323          I0 = I - 1
324          I1 = MIN( N, I+KA )
325          I2 = I - KBT + KA1
326          IF( I.LT.M+1 ) THEN
327             UPDATE = .FALSE.
328             I = I + 1
329             I0 = M
330             IF( KA.EQ.0 )
331      $         GO TO 480
332             GO TO 10
333          END IF
334       ELSE
335          I = I + KA
336          IF( I.GT.N-1 )
337      $      GO TO 480
338       END IF
339 *
340       IF( UPPER ) THEN
341 *
342 *        Transform A, working with the upper triangle
343 *
344          IF( UPDATE ) THEN
345 *
346 *           Form  inv(S(i))**H * A * inv(S(i))
347 *
348             BII = DBLE( BB( KB1, I ) )
349             AB( KA1, I ) = ( DBLE( AB( KA1, I ) ) / BII ) / BII
350             DO 20 J = I + 1, I1
351                AB( I-J+KA1, J ) = AB( I-J+KA1, J ) / BII
352    20       CONTINUE
353             DO 30 J = MAX( 1, I-KA ), I - 1
354                AB( J-I+KA1, I ) = AB( J-I+KA1, I ) / BII
355    30       CONTINUE
356             DO 60 K = I - KBT, I - 1
357                DO 40 J = I - KBT, K
358                   AB( J-K+KA1, K ) = AB( J-K+KA1, K ) -
359      $                               BB( J-I+KB1, I )*
360      $                               DCONJG( AB( K-I+KA1, I ) ) -
361      $                               DCONJG( BB( K-I+KB1, I ) )*
362      $                               AB( J-I+KA1, I ) +
363      $                               DBLE( AB( KA1, I ) )*
364      $                               BB( J-I+KB1, I )*
365      $                               DCONJG( BB( K-I+KB1, I ) )
366    40          CONTINUE
367                DO 50 J = MAX( 1, I-KA ), I - KBT - 1
368                   AB( J-K+KA1, K ) = AB( J-K+KA1, K ) -
369      $                               DCONJG( BB( K-I+KB1, I ) )*
370      $                               AB( J-I+KA1, I )
371    50          CONTINUE
372    60       CONTINUE
373             DO 80 J = I, I1
374                DO 70 K = MAX( J-KA, I-KBT ), I - 1
375                   AB( K-J+KA1, J ) = AB( K-J+KA1, J ) -
376      $                               BB( K-I+KB1, I )*AB( I-J+KA1, J )
377    70          CONTINUE
378    80       CONTINUE
379 *
380             IF( WANTX ) THEN
381 *
382 *              post-multiply X by inv(S(i))
383 *
384                CALL ZDSCAL( N-M, ONE / BII, X( M+1, I ), 1 )
385                IF( KBT.GT.0 )
386      $            CALL ZGERC( N-M, KBT, -CONE, X( M+1, I ), 1,
387      $                        BB( KB1-KBT, I ), 1, X( M+1, I-KBT ),
388      $                        LDX )
389             END IF
390 *
391 *           store a(i,i1) in RA1 for use in next loop over K
392 *
393             RA1 = AB( I-I1+KA1, I1 )
394          END IF
395 *
396 *        Generate and apply vectors of rotations to chase all the
397 *        existing bulges KA positions down toward the bottom of the
398 *        band
399 *
400          DO 130 K = 1, KB - 1
401             IF( UPDATE ) THEN
402 *
403 *              Determine the rotations which would annihilate the bulge
404 *              which has in theory just been created
405 *
406                IF( I-K+KA.LT.N .AND. I-K.GT.1 ) THEN
407 *
408 *                 generate rotation to annihilate a(i,i-k+ka+1)
409 *
410                   CALL ZLARTG( AB( K+1, I-K+KA ), RA1,
411      $                         RWORK( I-K+KA-M ), WORK( I-K+KA-M ), RA )
412 *
413 *                 create nonzero element a(i-k,i-k+ka+1) outside the
414 *                 band and store it in WORK(i-k)
415 *
416                   T = -BB( KB1-K, I )*RA1
417                   WORK( I-K ) = RWORK( I-K+KA-M )*T -
418      $                          DCONJG( WORK( I-K+KA-M ) )*
419      $                          AB( 1, I-K+KA )
420                   AB( 1, I-K+KA ) = WORK( I-K+KA-M )*T +
421      $                              RWORK( I-K+KA-M )*AB( 1, I-K+KA )
422                   RA1 = RA
423                END IF
424             END IF
425             J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1
426             NR = ( N-J2+KA ) / KA1
427             J1 = J2 + ( NR-1 )*KA1
428             IF( UPDATE ) THEN
429                J2T = MAX( J2, I+2*KA-K+1 )
430             ELSE
431                J2T = J2
432             END IF
433             NRT = ( N-J2T+KA ) / KA1
434             DO 90 J = J2T, J1, KA1
435 *
436 *              create nonzero element a(j-ka,j+1) outside the band
437 *              and store it in WORK(j-m)
438 *
439                WORK( J-M ) = WORK( J-M )*AB( 1, J+1 )
440                AB( 1, J+1 ) = RWORK( J-M )*AB( 1, J+1 )
441    90       CONTINUE
442 *
443 *           generate rotations in 1st set to annihilate elements which
444 *           have been created outside the band
445 *
446             IF( NRT.GT.0 )
447      $         CALL ZLARGV( NRT, AB( 1, J2T ), INCA, WORK( J2T-M ), KA1,
448      $                      RWORK( J2T-M ), KA1 )
449             IF( NR.GT.0 ) THEN
450 *
451 *              apply rotations in 1st set from the right
452 *
453                DO 100 L = 1, KA - 1
454                   CALL ZLARTV( NR, AB( KA1-L, J2 ), INCA,
455      $                         AB( KA-L, J2+1 ), INCA, RWORK( J2-M ),
456      $                         WORK( J2-M ), KA1 )
457   100          CONTINUE
458 *
459 *              apply rotations in 1st set from both sides to diagonal
460 *              blocks
461 *
462                CALL ZLAR2V( NR, AB( KA1, J2 ), AB( KA1, J2+1 ),
463      $                      AB( KA, J2+1 ), INCA, RWORK( J2-M ),
464      $                      WORK( J2-M ), KA1 )
465 *
466                CALL ZLACGV( NR, WORK( J2-M ), KA1 )
467             END IF
468 *
469 *           start applying rotations in 1st set from the left
470 *
471             DO 110 L = KA - 1, KB - K + 1, -1
472                NRT = ( N-J2+L ) / KA1
473                IF( NRT.GT.0 )
474      $            CALL ZLARTV( NRT, AB( L, J2+KA1-L ), INCA,
475      $                         AB( L+1, J2+KA1-L ), INCA, RWORK( J2-M ),
476      $                         WORK( J2-M ), KA1 )
477   110       CONTINUE
478 *
479             IF( WANTX ) THEN
480 *
481 *              post-multiply X by product of rotations in 1st set
482 *
483                DO 120 J = J2, J1, KA1
484                   CALL ZROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1,
485      $                       RWORK( J-M ), DCONJG( WORK( J-M ) ) )
486   120          CONTINUE
487             END IF
488   130    CONTINUE
489 *
490          IF( UPDATE ) THEN
491             IF( I2.LE.N .AND. KBT.GT.0 ) THEN
492 *
493 *              create nonzero element a(i-kbt,i-kbt+ka+1) outside the
494 *              band and store it in WORK(i-kbt)
495 *
496                WORK( I-KBT ) = -BB( KB1-KBT, I )*RA1
497             END IF
498          END IF
499 *
500          DO 170 K = KB, 1, -1
501             IF( UPDATE ) THEN
502                J2 = I - K - 1 + MAX( 2, K-I0+1 )*KA1
503             ELSE
504                J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1
505             END IF
506 *
507 *           finish applying rotations in 2nd set from the left
508 *
509             DO 140 L = KB - K, 1, -1
510                NRT = ( N-J2+KA+L ) / KA1
511                IF( NRT.GT.0 )
512      $            CALL ZLARTV( NRT, AB( L, J2-L+1 ), INCA,
513      $                         AB( L+1, J2-L+1 ), INCA, RWORK( J2-KA ),
514      $                         WORK( J2-KA ), KA1 )
515   140       CONTINUE
516             NR = ( N-J2+KA ) / KA1
517             J1 = J2 + ( NR-1 )*KA1
518             DO 150 J = J1, J2, -KA1
519                WORK( J ) = WORK( J-KA )
520                RWORK( J ) = RWORK( J-KA )
521   150       CONTINUE
522             DO 160 J = J2, J1, KA1
523 *
524 *              create nonzero element a(j-ka,j+1) outside the band
525 *              and store it in WORK(j)
526 *
527                WORK( J ) = WORK( J )*AB( 1, J+1 )
528                AB( 1, J+1 ) = RWORK( J )*AB( 1, J+1 )
529   160       CONTINUE
530             IF( UPDATE ) THEN
531                IF( I-K.LT.N-KA .AND. K.LE.KBT )
532      $            WORK( I-K+KA ) = WORK( I-K )
533             END IF
534   170    CONTINUE
535 *
536          DO 210 K = KB, 1, -1
537             J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1
538             NR = ( N-J2+KA ) / KA1
539             J1 = J2 + ( NR-1 )*KA1
540             IF( NR.GT.0 ) THEN
541 *
542 *              generate rotations in 2nd set to annihilate elements
543 *              which have been created outside the band
544 *
545                CALL ZLARGV( NR, AB( 1, J2 ), INCA, WORK( J2 ), KA1,
546      $                      RWORK( J2 ), KA1 )
547 *
548 *              apply rotations in 2nd set from the right
549 *
550                DO 180 L = 1, KA - 1
551                   CALL ZLARTV( NR, AB( KA1-L, J2 ), INCA,
552      $                         AB( KA-L, J2+1 ), INCA, RWORK( J2 ),
553      $                         WORK( J2 ), KA1 )
554   180          CONTINUE
555 *
556 *              apply rotations in 2nd set from both sides to diagonal
557 *              blocks
558 *
559                CALL ZLAR2V( NR, AB( KA1, J2 ), AB( KA1, J2+1 ),
560      $                      AB( KA, J2+1 ), INCA, RWORK( J2 ),
561      $                      WORK( J2 ), KA1 )
562 *
563                CALL ZLACGV( NR, WORK( J2 ), KA1 )
564             END IF
565 *
566 *           start applying rotations in 2nd set from the left
567 *
568             DO 190 L = KA - 1, KB - K + 1, -1
569                NRT = ( N-J2+L ) / KA1
570                IF( NRT.GT.0 )
571      $            CALL ZLARTV( NRT, AB( L, J2+KA1-L ), INCA,
572      $                         AB( L+1, J2+KA1-L ), INCA, RWORK( J2 ),
573      $                         WORK( J2 ), KA1 )
574   190       CONTINUE
575 *
576             IF( WANTX ) THEN
577 *
578 *              post-multiply X by product of rotations in 2nd set
579 *
580                DO 200 J = J2, J1, KA1
581                   CALL ZROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1,
582      $                       RWORK( J ), DCONJG( WORK( J ) ) )
583   200          CONTINUE
584             END IF
585   210    CONTINUE
586 *
587          DO 230 K = 1, KB - 1
588             J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1
589 *
590 *           finish applying rotations in 1st set from the left
591 *
592             DO 220 L = KB - K, 1, -1
593                NRT = ( N-J2+L ) / KA1
594                IF( NRT.GT.0 )
595      $            CALL ZLARTV( NRT, AB( L, J2+KA1-L ), INCA,
596      $                         AB( L+1, J2+KA1-L ), INCA, RWORK( J2-M ),
597      $                         WORK( J2-M ), KA1 )
598   220       CONTINUE
599   230    CONTINUE
600 *
601          IF( KB.GT.1 ) THEN
602             DO 240 J = N - 1, J2 + KA, -1
603                RWORK( J-M ) = RWORK( J-KA-M )
604                WORK( J-M ) = WORK( J-KA-M )
605   240       CONTINUE
606          END IF
607 *
608       ELSE
609 *
610 *        Transform A, working with the lower triangle
611 *
612          IF( UPDATE ) THEN
613 *
614 *           Form  inv(S(i))**H * A * inv(S(i))
615 *
616             BII = DBLE( BB( 1, I ) )
617             AB( 1, I ) = ( DBLE( AB( 1, I ) ) / BII ) / BII
618             DO 250 J = I + 1, I1
619                AB( J-I+1, I ) = AB( J-I+1, I ) / BII
620   250       CONTINUE
621             DO 260 J = MAX( 1, I-KA ), I - 1
622                AB( I-J+1, J ) = AB( I-J+1, J ) / BII
623   260       CONTINUE
624             DO 290 K = I - KBT, I - 1
625                DO 270 J = I - KBT, K
626                   AB( K-J+1, J ) = AB( K-J+1, J ) -
627      $                             BB( I-J+1, J )*DCONJG( AB( I-K+1,
628      $                             K ) ) - DCONJG( BB( I-K+1, K ) )*
629      $                             AB( I-J+1, J ) + DBLE( AB( 1, I ) )*
630      $                             BB( I-J+1, J )*DCONJG( BB( I-K+1,
631      $                             K ) )
632   270          CONTINUE
633                DO 280 J = MAX( 1, I-KA ), I - KBT - 1
634                   AB( K-J+1, J ) = AB( K-J+1, J ) -
635      $                             DCONJG( BB( I-K+1, K ) )*
636      $                             AB( I-J+1, J )
637   280          CONTINUE
638   290       CONTINUE
639             DO 310 J = I, I1
640                DO 300 K = MAX( J-KA, I-KBT ), I - 1
641                   AB( J-K+1, K ) = AB( J-K+1, K ) -
642      $                             BB( I-K+1, K )*AB( J-I+1, I )
643   300          CONTINUE
644   310       CONTINUE
645 *
646             IF( WANTX ) THEN
647 *
648 *              post-multiply X by inv(S(i))
649 *
650                CALL ZDSCAL( N-M, ONE / BII, X( M+1, I ), 1 )
651                IF( KBT.GT.0 )
652      $            CALL ZGERU( N-M, KBT, -CONE, X( M+1, I ), 1,
653      $                        BB( KBT+1, I-KBT ), LDBB-1,
654      $                        X( M+1, I-KBT ), LDX )
655             END IF
656 *
657 *           store a(i1,i) in RA1 for use in next loop over K
658 *
659             RA1 = AB( I1-I+1, I )
660          END IF
661 *
662 *        Generate and apply vectors of rotations to chase all the
663 *        existing bulges KA positions down toward the bottom of the
664 *        band
665 *
666          DO 360 K = 1, KB - 1
667             IF( UPDATE ) THEN
668 *
669 *              Determine the rotations which would annihilate the bulge
670 *              which has in theory just been created
671 *
672                IF( I-K+KA.LT.N .AND. I-K.GT.1 ) THEN
673 *
674 *                 generate rotation to annihilate a(i-k+ka+1,i)
675 *
676                   CALL ZLARTG( AB( KA1-K, I ), RA1, RWORK( I-K+KA-M ),
677      $                         WORK( I-K+KA-M ), RA )
678 *
679 *                 create nonzero element a(i-k+ka+1,i-k) outside the
680 *                 band and store it in WORK(i-k)
681 *
682                   T = -BB( K+1, I-K )*RA1
683                   WORK( I-K ) = RWORK( I-K+KA-M )*T -
684      $                          DCONJG( WORK( I-K+KA-M ) )*
685      $                          AB( KA1, I-K )
686                   AB( KA1, I-K ) = WORK( I-K+KA-M )*T +
687      $                             RWORK( I-K+KA-M )*AB( KA1, I-K )
688                   RA1 = RA
689                END IF
690             END IF
691             J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1
692             NR = ( N-J2+KA ) / KA1
693             J1 = J2 + ( NR-1 )*KA1
694             IF( UPDATE ) THEN
695                J2T = MAX( J2, I+2*KA-K+1 )
696             ELSE
697                J2T = J2
698             END IF
699             NRT = ( N-J2T+KA ) / KA1
700             DO 320 J = J2T, J1, KA1
701 *
702 *              create nonzero element a(j+1,j-ka) outside the band
703 *              and store it in WORK(j-m)
704 *
705                WORK( J-M ) = WORK( J-M )*AB( KA1, J-KA+1 )
706                AB( KA1, J-KA+1 ) = RWORK( J-M )*AB( KA1, J-KA+1 )
707   320       CONTINUE
708 *
709 *           generate rotations in 1st set to annihilate elements which
710 *           have been created outside the band
711 *
712             IF( NRT.GT.0 )
713      $         CALL ZLARGV( NRT, AB( KA1, J2T-KA ), INCA, WORK( J2T-M ),
714      $                      KA1, RWORK( J2T-M ), KA1 )
715             IF( NR.GT.0 ) THEN
716 *
717 *              apply rotations in 1st set from the left
718 *
719                DO 330 L = 1, KA - 1
720                   CALL ZLARTV( NR, AB( L+1, J2-L ), INCA,
721      $                         AB( L+2, J2-L ), INCA, RWORK( J2-M ),
722      $                         WORK( J2-M ), KA1 )
723   330          CONTINUE
724 *
725 *              apply rotations in 1st set from both sides to diagonal
726 *              blocks
727 *
728                CALL ZLAR2V( NR, AB( 1, J2 ), AB( 1, J2+1 ), AB( 2, J2 ),
729      $                      INCA, RWORK( J2-M ), WORK( J2-M ), KA1 )
730 *
731                CALL ZLACGV( NR, WORK( J2-M ), KA1 )
732             END IF
733 *
734 *           start applying rotations in 1st set from the right
735 *
736             DO 340 L = KA - 1, KB - K + 1, -1
737                NRT = ( N-J2+L ) / KA1
738                IF( NRT.GT.0 )
739      $            CALL ZLARTV( NRT, AB( KA1-L+1, J2 ), INCA,
740      $                         AB( KA1-L, J2+1 ), INCA, RWORK( J2-M ),
741      $                         WORK( J2-M ), KA1 )
742   340       CONTINUE
743 *
744             IF( WANTX ) THEN
745 *
746 *              post-multiply X by product of rotations in 1st set
747 *
748                DO 350 J = J2, J1, KA1
749                   CALL ZROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1,
750      $                       RWORK( J-M ), WORK( J-M ) )
751   350          CONTINUE
752             END IF
753   360    CONTINUE
754 *
755          IF( UPDATE ) THEN
756             IF( I2.LE.N .AND. KBT.GT.0 ) THEN
757 *
758 *              create nonzero element a(i-kbt+ka+1,i-kbt) outside the
759 *              band and store it in WORK(i-kbt)
760 *
761                WORK( I-KBT ) = -BB( KBT+1, I-KBT )*RA1
762             END IF
763          END IF
764 *
765          DO 400 K = KB, 1, -1
766             IF( UPDATE ) THEN
767                J2 = I - K - 1 + MAX( 2, K-I0+1 )*KA1
768             ELSE
769                J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1
770             END IF
771 *
772 *           finish applying rotations in 2nd set from the right
773 *
774             DO 370 L = KB - K, 1, -1
775                NRT = ( N-J2+KA+L ) / KA1
776                IF( NRT.GT.0 )
777      $            CALL ZLARTV( NRT, AB( KA1-L+1, J2-KA ), INCA,
778      $                         AB( KA1-L, J2-KA+1 ), INCA,
779      $                         RWORK( J2-KA ), WORK( J2-KA ), KA1 )
780   370       CONTINUE
781             NR = ( N-J2+KA ) / KA1
782             J1 = J2 + ( NR-1 )*KA1
783             DO 380 J = J1, J2, -KA1
784                WORK( J ) = WORK( J-KA )
785                RWORK( J ) = RWORK( J-KA )
786   380       CONTINUE
787             DO 390 J = J2, J1, KA1
788 *
789 *              create nonzero element a(j+1,j-ka) outside the band
790 *              and store it in WORK(j)
791 *
792                WORK( J ) = WORK( J )*AB( KA1, J-KA+1 )
793                AB( KA1, J-KA+1 ) = RWORK( J )*AB( KA1, J-KA+1 )
794   390       CONTINUE
795             IF( UPDATE ) THEN
796                IF( I-K.LT.N-KA .AND. K.LE.KBT )
797      $            WORK( I-K+KA ) = WORK( I-K )
798             END IF
799   400    CONTINUE
800 *
801          DO 440 K = KB, 1, -1
802             J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1
803             NR = ( N-J2+KA ) / KA1
804             J1 = J2 + ( NR-1 )*KA1
805             IF( NR.GT.0 ) THEN
806 *
807 *              generate rotations in 2nd set to annihilate elements
808 *              which have been created outside the band
809 *
810                CALL ZLARGV( NR, AB( KA1, J2-KA ), INCA, WORK( J2 ), KA1,
811      $                      RWORK( J2 ), KA1 )
812 *
813 *              apply rotations in 2nd set from the left
814 *
815                DO 410 L = 1, KA - 1
816                   CALL ZLARTV( NR, AB( L+1, J2-L ), INCA,
817      $                         AB( L+2, J2-L ), INCA, RWORK( J2 ),
818      $                         WORK( J2 ), KA1 )
819   410          CONTINUE
820 *
821 *              apply rotations in 2nd set from both sides to diagonal
822 *              blocks
823 *
824                CALL ZLAR2V( NR, AB( 1, J2 ), AB( 1, J2+1 ), AB( 2, J2 ),
825      $                      INCA, RWORK( J2 ), WORK( J2 ), KA1 )
826 *
827                CALL ZLACGV( NR, WORK( J2 ), KA1 )
828             END IF
829 *
830 *           start applying rotations in 2nd set from the right
831 *
832             DO 420 L = KA - 1, KB - K + 1, -1
833                NRT = ( N-J2+L ) / KA1
834                IF( NRT.GT.0 )
835      $            CALL ZLARTV( NRT, AB( KA1-L+1, J2 ), INCA,
836      $                         AB( KA1-L, J2+1 ), INCA, RWORK( J2 ),
837      $                         WORK( J2 ), KA1 )
838   420       CONTINUE
839 *
840             IF( WANTX ) THEN
841 *
842 *              post-multiply X by product of rotations in 2nd set
843 *
844                DO 430 J = J2, J1, KA1
845                   CALL ZROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1,
846      $                       RWORK( J ), WORK( J ) )
847   430          CONTINUE
848             END IF
849   440    CONTINUE
850 *
851          DO 460 K = 1, KB - 1
852             J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1
853 *
854 *           finish applying rotations in 1st set from the right
855 *
856             DO 450 L = KB - K, 1, -1
857                NRT = ( N-J2+L ) / KA1
858                IF( NRT.GT.0 )
859      $            CALL ZLARTV( NRT, AB( KA1-L+1, J2 ), INCA,
860      $                         AB( KA1-L, J2+1 ), INCA, RWORK( J2-M ),
861      $                         WORK( J2-M ), KA1 )
862   450       CONTINUE
863   460    CONTINUE
864 *
865          IF( KB.GT.1 ) THEN
866             DO 470 J = N - 1, J2 + KA, -1
867                RWORK( J-M ) = RWORK( J-KA-M )
868                WORK( J-M ) = WORK( J-KA-M )
869   470       CONTINUE
870          END IF
871 *
872       END IF
873 *
874       GO TO 10
875 *
876   480 CONTINUE
877 *
878 *     **************************** Phase 2 *****************************
879 *
880 *     The logical structure of this phase is:
881 *
882 *     UPDATE = .TRUE.
883 *     DO I = 1, M
884 *        use S(i) to update A and create a new bulge
885 *        apply rotations to push all bulges KA positions upward
886 *     END DO
887 *     UPDATE = .FALSE.
888 *     DO I = M - KA - 1, 2, -1
889 *        apply rotations to push all bulges KA positions upward
890 *     END DO
891 *
892 *     To avoid duplicating code, the two loops are merged.
893 *
894       UPDATE = .TRUE.
895       I = 0
896   490 CONTINUE
897       IF( UPDATE ) THEN
898          I = I + 1
899          KBT = MIN( KB, M-I )
900          I0 = I + 1
901          I1 = MAX( 1, I-KA )
902          I2 = I + KBT - KA1
903          IF( I.GT.M ) THEN
904             UPDATE = .FALSE.
905             I = I - 1
906             I0 = M + 1
907             IF( KA.EQ.0 )
908      $         RETURN
909             GO TO 490
910          END IF
911       ELSE
912          I = I - KA
913          IF( I.LT.2 )
914      $      RETURN
915       END IF
916 *
917       IF( I.LT.M-KBT ) THEN
918          NX = M
919       ELSE
920          NX = N
921       END IF
922 *
923       IF( UPPER ) THEN
924 *
925 *        Transform A, working with the upper triangle
926 *
927          IF( UPDATE ) THEN
928 *
929 *           Form  inv(S(i))**H * A * inv(S(i))
930 *
931             BII = DBLE( BB( KB1, I ) )
932             AB( KA1, I ) = ( DBLE( AB( KA1, I ) ) / BII ) / BII
933             DO 500 J = I1, I - 1
934                AB( J-I+KA1, I ) = AB( J-I+KA1, I ) / BII
935   500       CONTINUE
936             DO 510 J = I + 1, MIN( N, I+KA )
937                AB( I-J+KA1, J ) = AB( I-J+KA1, J ) / BII
938   510       CONTINUE
939             DO 540 K = I + 1, I + KBT
940                DO 520 J = K, I + KBT
941                   AB( K-J+KA1, J ) = AB( K-J+KA1, J ) -
942      $                               BB( I-J+KB1, J )*
943      $                               DCONJG( AB( I-K+KA1, K ) ) -
944      $                               DCONJG( BB( I-K+KB1, K ) )*
945      $                               AB( I-J+KA1, J ) +
946      $                               DBLE( AB( KA1, I ) )*
947      $                               BB( I-J+KB1, J )*
948      $                               DCONJG( BB( I-K+KB1, K ) )
949   520          CONTINUE
950                DO 530 J = I + KBT + 1, MIN( N, I+KA )
951                   AB( K-J+KA1, J ) = AB( K-J+KA1, J ) -
952      $                               DCONJG( BB( I-K+KB1, K ) )*
953      $                               AB( I-J+KA1, J )
954   530          CONTINUE
955   540       CONTINUE
956             DO 560 J = I1, I
957                DO 550 K = I + 1, MIN( J+KA, I+KBT )
958                   AB( J-K+KA1, K ) = AB( J-K+KA1, K ) -
959      $                               BB( I-K+KB1, K )*AB( J-I+KA1, I )
960   550          CONTINUE
961   560       CONTINUE
962 *
963             IF( WANTX ) THEN
964 *
965 *              post-multiply X by inv(S(i))
966 *
967                CALL ZDSCAL( NX, ONE / BII, X( 1, I ), 1 )
968                IF( KBT.GT.0 )
969      $            CALL ZGERU( NX, KBT, -CONE, X( 1, I ), 1,
970      $                        BB( KB, I+1 ), LDBB-1, X( 1, I+1 ), LDX )
971             END IF
972 *
973 *           store a(i1,i) in RA1 for use in next loop over K
974 *
975             RA1 = AB( I1-I+KA1, I )
976          END IF
977 *
978 *        Generate and apply vectors of rotations to chase all the
979 *        existing bulges KA positions up toward the top of the band
980 *
981          DO 610 K = 1, KB - 1
982             IF( UPDATE ) THEN
983 *
984 *              Determine the rotations which would annihilate the bulge
985 *              which has in theory just been created
986 *
987                IF( I+K-KA1.GT.0 .AND. I+K.LT.M ) THEN
988 *
989 *                 generate rotation to annihilate a(i+k-ka-1,i)
990 *
991                   CALL ZLARTG( AB( K+1, I ), RA1, RWORK( I+K-KA ),
992      $                         WORK( I+K-KA ), RA )
993 *
994 *                 create nonzero element a(i+k-ka-1,i+k) outside the
995 *                 band and store it in WORK(m-kb+i+k)
996 *
997                   T = -BB( KB1-K, I+K )*RA1
998                   WORK( M-KB+I+K ) = RWORK( I+K-KA )*T -
999      $                               DCONJG( WORK( I+K-KA ) )*
1000      $                               AB( 1, I+K )
1001                   AB( 1, I+K ) = WORK( I+K-KA )*T +
1002      $                           RWORK( I+K-KA )*AB( 1, I+K )
1003                   RA1 = RA
1004                END IF
1005             END IF
1006             J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1
1007             NR = ( J2+KA-1 ) / KA1
1008             J1 = J2 - ( NR-1 )*KA1
1009             IF( UPDATE ) THEN
1010                J2T = MIN( J2, I-2*KA+K-1 )
1011             ELSE
1012                J2T = J2
1013             END IF
1014             NRT = ( J2T+KA-1 ) / KA1
1015             DO 570 J = J1, J2T, KA1
1016 *
1017 *              create nonzero element a(j-1,j+ka) outside the band
1018 *              and store it in WORK(j)
1019 *
1020                WORK( J ) = WORK( J )*AB( 1, J+KA-1 )
1021                AB( 1, J+KA-1 ) = RWORK( J )*AB( 1, J+KA-1 )
1022   570       CONTINUE
1023 *
1024 *           generate rotations in 1st set to annihilate elements which
1025 *           have been created outside the band
1026 *
1027             IF( NRT.GT.0 )
1028      $         CALL ZLARGV( NRT, AB( 1, J1+KA ), INCA, WORK( J1 ), KA1,
1029      $                      RWORK( J1 ), KA1 )
1030             IF( NR.GT.0 ) THEN
1031 *
1032 *              apply rotations in 1st set from the left
1033 *
1034                DO 580 L = 1, KA - 1
1035                   CALL ZLARTV( NR, AB( KA1-L, J1+L ), INCA,
1036      $                         AB( KA-L, J1+L ), INCA, RWORK( J1 ),
1037      $                         WORK( J1 ), KA1 )
1038   580          CONTINUE
1039 *
1040 *              apply rotations in 1st set from both sides to diagonal
1041 *              blocks
1042 *
1043                CALL ZLAR2V( NR, AB( KA1, J1 ), AB( KA1, J1-1 ),
1044      $                      AB( KA, J1 ), INCA, RWORK( J1 ), WORK( J1 ),
1045      $                      KA1 )
1046 *
1047                CALL ZLACGV( NR, WORK( J1 ), KA1 )
1048             END IF
1049 *
1050 *           start applying rotations in 1st set from the right
1051 *
1052             DO 590 L = KA - 1, KB - K + 1, -1
1053                NRT = ( J2+L-1 ) / KA1
1054                J1T = J2 - ( NRT-1 )*KA1
1055                IF( NRT.GT.0 )
1056      $            CALL ZLARTV( NRT, AB( L, J1T ), INCA,
1057      $                         AB( L+1, J1T-1 ), INCA, RWORK( J1T ),
1058      $                         WORK( J1T ), KA1 )
1059   590       CONTINUE
1060 *
1061             IF( WANTX ) THEN
1062 *
1063 *              post-multiply X by product of rotations in 1st set
1064 *
1065                DO 600 J = J1, J2, KA1
1066                   CALL ZROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1,
1067      $                       RWORK( J ), WORK( J ) )
1068   600          CONTINUE
1069             END IF
1070   610    CONTINUE
1071 *
1072          IF( UPDATE ) THEN
1073             IF( I2.GT.0 .AND. KBT.GT.0 ) THEN
1074 *
1075 *              create nonzero element a(i+kbt-ka-1,i+kbt) outside the
1076 *              band and store it in WORK(m-kb+i+kbt)
1077 *
1078                WORK( M-KB+I+KBT ) = -BB( KB1-KBT, I+KBT )*RA1
1079             END IF
1080          END IF
1081 *
1082          DO 650 K = KB, 1, -1
1083             IF( UPDATE ) THEN
1084                J2 = I + K + 1 - MAX( 2, K+I0-M )*KA1
1085             ELSE
1086                J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1
1087             END IF
1088 *
1089 *           finish applying rotations in 2nd set from the right
1090 *
1091             DO 620 L = KB - K, 1, -1
1092                NRT = ( J2+KA+L-1 ) / KA1
1093                J1T = J2 - ( NRT-1 )*KA1
1094                IF( NRT.GT.0 )
1095      $            CALL ZLARTV( NRT, AB( L, J1T+KA ), INCA,
1096      $                         AB( L+1, J1T+KA-1 ), INCA,
1097      $                         RWORK( M-KB+J1T+KA ),
1098      $                         WORK( M-KB+J1T+KA ), KA1 )
1099   620       CONTINUE
1100             NR = ( J2+KA-1 ) / KA1
1101             J1 = J2 - ( NR-1 )*KA1
1102             DO 630 J = J1, J2, KA1
1103                WORK( M-KB+J ) = WORK( M-KB+J+KA )
1104                RWORK( M-KB+J ) = RWORK( M-KB+J+KA )
1105   630       CONTINUE
1106             DO 640 J = J1, J2, KA1
1107 *
1108 *              create nonzero element a(j-1,j+ka) outside the band
1109 *              and store it in WORK(m-kb+j)
1110 *
1111                WORK( M-KB+J ) = WORK( M-KB+J )*AB( 1, J+KA-1 )
1112                AB( 1, J+KA-1 ) = RWORK( M-KB+J )*AB( 1, J+KA-1 )
1113   640       CONTINUE
1114             IF( UPDATE ) THEN
1115                IF( I+K.GT.KA1 .AND. K.LE.KBT )
1116      $            WORK( M-KB+I+K-KA ) = WORK( M-KB+I+K )
1117             END IF
1118   650    CONTINUE
1119 *
1120          DO 690 K = KB, 1, -1
1121             J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1
1122             NR = ( J2+KA-1 ) / KA1
1123             J1 = J2 - ( NR-1 )*KA1
1124             IF( NR.GT.0 ) THEN
1125 *
1126 *              generate rotations in 2nd set to annihilate elements
1127 *              which have been created outside the band
1128 *
1129                CALL ZLARGV( NR, AB( 1, J1+KA ), INCA, WORK( M-KB+J1 ),
1130      $                      KA1, RWORK( M-KB+J1 ), KA1 )
1131 *
1132 *              apply rotations in 2nd set from the left
1133 *
1134                DO 660 L = 1, KA - 1
1135                   CALL ZLARTV( NR, AB( KA1-L, J1+L ), INCA,
1136      $                         AB( KA-L, J1+L ), INCA, RWORK( M-KB+J1 ),
1137      $                         WORK( M-KB+J1 ), KA1 )
1138   660          CONTINUE
1139 *
1140 *              apply rotations in 2nd set from both sides to diagonal
1141 *              blocks
1142 *
1143                CALL ZLAR2V( NR, AB( KA1, J1 ), AB( KA1, J1-1 ),
1144      $                      AB( KA, J1 ), INCA, RWORK( M-KB+J1 ),
1145      $                      WORK( M-KB+J1 ), KA1 )
1146 *
1147                CALL ZLACGV( NR, WORK( M-KB+J1 ), KA1 )
1148             END IF
1149 *
1150 *           start applying rotations in 2nd set from the right
1151 *
1152             DO 670 L = KA - 1, KB - K + 1, -1
1153                NRT = ( J2+L-1 ) / KA1
1154                J1T = J2 - ( NRT-1 )*KA1
1155                IF( NRT.GT.0 )
1156      $            CALL ZLARTV( NRT, AB( L, J1T ), INCA,
1157      $                         AB( L+1, J1T-1 ), INCA,
1158      $                         RWORK( M-KB+J1T ), WORK( M-KB+J1T ),
1159      $                         KA1 )
1160   670       CONTINUE
1161 *
1162             IF( WANTX ) THEN
1163 *
1164 *              post-multiply X by product of rotations in 2nd set
1165 *
1166                DO 680 J = J1, J2, KA1
1167                   CALL ZROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1,
1168      $                       RWORK( M-KB+J ), WORK( M-KB+J ) )
1169   680          CONTINUE
1170             END IF
1171   690    CONTINUE
1172 *
1173          DO 710 K = 1, KB - 1
1174             J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1
1175 *
1176 *           finish applying rotations in 1st set from the right
1177 *
1178             DO 700 L = KB - K, 1, -1
1179                NRT = ( J2+L-1 ) / KA1
1180                J1T = J2 - ( NRT-1 )*KA1
1181                IF( NRT.GT.0 )
1182      $            CALL ZLARTV( NRT, AB( L, J1T ), INCA,
1183      $                         AB( L+1, J1T-1 ), INCA, RWORK( J1T ),
1184      $                         WORK( J1T ), KA1 )
1185   700       CONTINUE
1186   710    CONTINUE
1187 *
1188          IF( KB.GT.1 ) THEN
1189             DO 720 J = 2, I2 - KA
1190                RWORK( J ) = RWORK( J+KA )
1191                WORK( J ) = WORK( J+KA )
1192   720       CONTINUE
1193          END IF
1194 *
1195       ELSE
1196 *
1197 *        Transform A, working with the lower triangle
1198 *
1199          IF( UPDATE ) THEN
1200 *
1201 *           Form  inv(S(i))**H * A * inv(S(i))
1202 *
1203             BII = DBLE( BB( 1, I ) )
1204             AB( 1, I ) = ( DBLE( AB( 1, I ) ) / BII ) / BII
1205             DO 730 J = I1, I - 1
1206                AB( I-J+1, J ) = AB( I-J+1, J ) / BII
1207   730       CONTINUE
1208             DO 740 J = I + 1, MIN( N, I+KA )
1209                AB( J-I+1, I ) = AB( J-I+1, I ) / BII
1210   740       CONTINUE
1211             DO 770 K = I + 1, I + KBT
1212                DO 750 J = K, I + KBT
1213                   AB( J-K+1, K ) = AB( J-K+1, K ) -
1214      $                             BB( J-I+1, I )*DCONJG( AB( K-I+1,
1215      $                             I ) ) - DCONJG( BB( K-I+1, I ) )*
1216      $                             AB( J-I+1, I ) + DBLE( AB( 1, I ) )*
1217      $                             BB( J-I+1, I )*DCONJG( BB( K-I+1,
1218      $                             I ) )
1219   750          CONTINUE
1220                DO 760 J = I + KBT + 1, MIN( N, I+KA )
1221                   AB( J-K+1, K ) = AB( J-K+1, K ) -
1222      $                             DCONJG( BB( K-I+1, I ) )*
1223      $                             AB( J-I+1, I )
1224   760          CONTINUE
1225   770       CONTINUE
1226             DO 790 J = I1, I
1227                DO 780 K = I + 1, MIN( J+KA, I+KBT )
1228                   AB( K-J+1, J ) = AB( K-J+1, J ) -
1229      $                             BB( K-I+1, I )*AB( I-J+1, J )
1230   780          CONTINUE
1231   790       CONTINUE
1232 *
1233             IF( WANTX ) THEN
1234 *
1235 *              post-multiply X by inv(S(i))
1236 *
1237                CALL ZDSCAL( NX, ONE / BII, X( 1, I ), 1 )
1238                IF( KBT.GT.0 )
1239      $            CALL ZGERC( NX, KBT, -CONE, X( 1, I ), 1, BB( 2, I ),
1240      $                        1, X( 1, I+1 ), LDX )
1241             END IF
1242 *
1243 *           store a(i,i1) in RA1 for use in next loop over K
1244 *
1245             RA1 = AB( I-I1+1, I1 )
1246          END IF
1247 *
1248 *        Generate and apply vectors of rotations to chase all the
1249 *        existing bulges KA positions up toward the top of the band
1250 *
1251          DO 840 K = 1, KB - 1
1252             IF( UPDATE ) THEN
1253 *
1254 *              Determine the rotations which would annihilate the bulge
1255 *              which has in theory just been created
1256 *
1257                IF( I+K-KA1.GT.0 .AND. I+K.LT.M ) THEN
1258 *
1259 *                 generate rotation to annihilate a(i,i+k-ka-1)
1260 *
1261                   CALL ZLARTG( AB( KA1-K, I+K-KA ), RA1,
1262      $                         RWORK( I+K-KA ), WORK( I+K-KA ), RA )
1263 *
1264 *                 create nonzero element a(i+k,i+k-ka-1) outside the
1265 *                 band and store it in WORK(m-kb+i+k)
1266 *
1267                   T = -BB( K+1, I )*RA1
1268                   WORK( M-KB+I+K ) = RWORK( I+K-KA )*T -
1269      $                               DCONJG( WORK( I+K-KA ) )*
1270      $                               AB( KA1, I+K-KA )
1271                   AB( KA1, I+K-KA ) = WORK( I+K-KA )*T +
1272      $                                RWORK( I+K-KA )*AB( KA1, I+K-KA )
1273                   RA1 = RA
1274                END IF
1275             END IF
1276             J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1
1277             NR = ( J2+KA-1 ) / KA1
1278             J1 = J2 - ( NR-1 )*KA1
1279             IF( UPDATE ) THEN
1280                J2T = MIN( J2, I-2*KA+K-1 )
1281             ELSE
1282                J2T = J2
1283             END IF
1284             NRT = ( J2T+KA-1 ) / KA1
1285             DO 800 J = J1, J2T, KA1
1286 *
1287 *              create nonzero element a(j+ka,j-1) outside the band
1288 *              and store it in WORK(j)
1289 *
1290                WORK( J ) = WORK( J )*AB( KA1, J-1 )
1291                AB( KA1, J-1 ) = RWORK( J )*AB( KA1, J-1 )
1292   800       CONTINUE
1293 *
1294 *           generate rotations in 1st set to annihilate elements which
1295 *           have been created outside the band
1296 *
1297             IF( NRT.GT.0 )
1298      $         CALL ZLARGV( NRT, AB( KA1, J1 ), INCA, WORK( J1 ), KA1,
1299      $                      RWORK( J1 ), KA1 )
1300             IF( NR.GT.0 ) THEN
1301 *
1302 *              apply rotations in 1st set from the right
1303 *
1304                DO 810 L = 1, KA - 1
1305                   CALL ZLARTV( NR, AB( L+1, J1 ), INCA, AB( L+2, J1-1 ),
1306      $                         INCA, RWORK( J1 ), WORK( J1 ), KA1 )
1307   810          CONTINUE
1308 *
1309 *              apply rotations in 1st set from both sides to diagonal
1310 *              blocks
1311 *
1312                CALL ZLAR2V( NR, AB( 1, J1 ), AB( 1, J1-1 ),
1313      $                      AB( 2, J1-1 ), INCA, RWORK( J1 ),
1314      $                      WORK( J1 ), KA1 )
1315 *
1316                CALL ZLACGV( NR, WORK( J1 ), KA1 )
1317             END IF
1318 *
1319 *           start applying rotations in 1st set from the left
1320 *
1321             DO 820 L = KA - 1, KB - K + 1, -1
1322                NRT = ( J2+L-1 ) / KA1
1323                J1T = J2 - ( NRT-1 )*KA1
1324                IF( NRT.GT.0 )
1325      $            CALL ZLARTV( NRT, AB( KA1-L+1, J1T-KA1+L ), INCA,
1326      $                         AB( KA1-L, J1T-KA1+L ), INCA,
1327      $                         RWORK( J1T ), WORK( J1T ), KA1 )
1328   820       CONTINUE
1329 *
1330             IF( WANTX ) THEN
1331 *
1332 *              post-multiply X by product of rotations in 1st set
1333 *
1334                DO 830 J = J1, J2, KA1
1335                   CALL ZROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1,
1336      $                       RWORK( J ), DCONJG( WORK( J ) ) )
1337   830          CONTINUE
1338             END IF
1339   840    CONTINUE
1340 *
1341          IF( UPDATE ) THEN
1342             IF( I2.GT.0 .AND. KBT.GT.0 ) THEN
1343 *
1344 *              create nonzero element a(i+kbt,i+kbt-ka-1) outside the
1345 *              band and store it in WORK(m-kb+i+kbt)
1346 *
1347                WORK( M-KB+I+KBT ) = -BB( KBT+1, I )*RA1
1348             END IF
1349          END IF
1350 *
1351          DO 880 K = KB, 1, -1
1352             IF( UPDATE ) THEN
1353                J2 = I + K + 1 - MAX( 2, K+I0-M )*KA1
1354             ELSE
1355                J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1
1356             END IF
1357 *
1358 *           finish applying rotations in 2nd set from the left
1359 *
1360             DO 850 L = KB - K, 1, -1
1361                NRT = ( J2+KA+L-1 ) / KA1
1362                J1T = J2 - ( NRT-1 )*KA1
1363                IF( NRT.GT.0 )
1364      $            CALL ZLARTV( NRT, AB( KA1-L+1, J1T+L-1 ), INCA,
1365      $                         AB( KA1-L, J1T+L-1 ), INCA,
1366      $                         RWORK( M-KB+J1T+KA ),
1367      $                         WORK( M-KB+J1T+KA ), KA1 )
1368   850       CONTINUE
1369             NR = ( J2+KA-1 ) / KA1
1370             J1 = J2 - ( NR-1 )*KA1
1371             DO 860 J = J1, J2, KA1
1372                WORK( M-KB+J ) = WORK( M-KB+J+KA )
1373                RWORK( M-KB+J ) = RWORK( M-KB+J+KA )
1374   860       CONTINUE
1375             DO 870 J = J1, J2, KA1
1376 *
1377 *              create nonzero element a(j+ka,j-1) outside the band
1378 *              and store it in WORK(m-kb+j)
1379 *
1380                WORK( M-KB+J ) = WORK( M-KB+J )*AB( KA1, J-1 )
1381                AB( KA1, J-1 ) = RWORK( M-KB+J )*AB( KA1, J-1 )
1382   870       CONTINUE
1383             IF( UPDATE ) THEN
1384                IF( I+K.GT.KA1 .AND. K.LE.KBT )
1385      $            WORK( M-KB+I+K-KA ) = WORK( M-KB+I+K )
1386             END IF
1387   880    CONTINUE
1388 *
1389          DO 920 K = KB, 1, -1
1390             J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1
1391             NR = ( J2+KA-1 ) / KA1
1392             J1 = J2 - ( NR-1 )*KA1
1393             IF( NR.GT.0 ) THEN
1394 *
1395 *              generate rotations in 2nd set to annihilate elements
1396 *              which have been created outside the band
1397 *
1398                CALL ZLARGV( NR, AB( KA1, J1 ), INCA, WORK( M-KB+J1 ),
1399      $                      KA1, RWORK( M-KB+J1 ), KA1 )
1400 *
1401 *              apply rotations in 2nd set from the right
1402 *
1403                DO 890 L = 1, KA - 1
1404                   CALL ZLARTV( NR, AB( L+1, J1 ), INCA, AB( L+2, J1-1 ),
1405      $                         INCA, RWORK( M-KB+J1 ), WORK( M-KB+J1 ),
1406      $                         KA1 )
1407   890          CONTINUE
1408 *
1409 *              apply rotations in 2nd set from both sides to diagonal
1410 *              blocks
1411 *
1412                CALL ZLAR2V( NR, AB( 1, J1 ), AB( 1, J1-1 ),
1413      $                      AB( 2, J1-1 ), INCA, RWORK( M-KB+J1 ),
1414      $                      WORK( M-KB+J1 ), KA1 )
1415 *
1416                CALL ZLACGV( NR, WORK( M-KB+J1 ), KA1 )
1417             END IF
1418 *
1419 *           start applying rotations in 2nd set from the left
1420 *
1421             DO 900 L = KA - 1, KB - K + 1, -1
1422                NRT = ( J2+L-1 ) / KA1
1423                J1T = J2 - ( NRT-1 )*KA1
1424                IF( NRT.GT.0 )
1425      $            CALL ZLARTV( NRT, AB( KA1-L+1, J1T-KA1+L ), INCA,
1426      $                         AB( KA1-L, J1T-KA1+L ), INCA,
1427      $                         RWORK( M-KB+J1T ), WORK( M-KB+J1T ),
1428      $                         KA1 )
1429   900       CONTINUE
1430 *
1431             IF( WANTX ) THEN
1432 *
1433 *              post-multiply X by product of rotations in 2nd set
1434 *
1435                DO 910 J = J1, J2, KA1
1436                   CALL ZROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1,
1437      $                       RWORK( M-KB+J ), DCONJG( WORK( M-KB+J ) ) )
1438   910          CONTINUE
1439             END IF
1440   920    CONTINUE
1441 *
1442          DO 940 K = 1, KB - 1
1443             J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1
1444 *
1445 *           finish applying rotations in 1st set from the left
1446 *
1447             DO 930 L = KB - K, 1, -1
1448                NRT = ( J2+L-1 ) / KA1
1449                J1T = J2 - ( NRT-1 )*KA1
1450                IF( NRT.GT.0 )
1451      $            CALL ZLARTV( NRT, AB( KA1-L+1, J1T-KA1+L ), INCA,
1452      $                         AB( KA1-L, J1T-KA1+L ), INCA,
1453      $                         RWORK( J1T ), WORK( J1T ), KA1 )
1454   930       CONTINUE
1455   940    CONTINUE
1456 *
1457          IF( KB.GT.1 ) THEN
1458             DO 950 J = 2, I2 - KA
1459                RWORK( J ) = RWORK( J+KA )
1460                WORK( J ) = WORK( J+KA )
1461   950       CONTINUE
1462          END IF
1463 *
1464       END IF
1465 *
1466       GO TO 490
1467 *
1468 *     End of ZHBGST
1469 *
1470       END