LAPACK 3.3.1
Linear Algebra PACKage

zhbgst.f

Go to the documentation of this file.
00001       SUBROUTINE ZHBGST( VECT, UPLO, N, KA, KB, AB, LDAB, BB, LDBB, X,
00002      $                   LDX, WORK, RWORK, INFO )
00003 *
00004 *  -- LAPACK routine (version 3.2.2) --
00005 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
00006 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
00007 *     June 2010
00008 *
00009 *     .. Scalar Arguments ..
00010       CHARACTER          UPLO, VECT
00011       INTEGER            INFO, KA, KB, LDAB, LDBB, LDX, N
00012 *     ..
00013 *     .. Array Arguments ..
00014       DOUBLE PRECISION   RWORK( * )
00015       COMPLEX*16         AB( LDAB, * ), BB( LDBB, * ), WORK( * ),
00016      $                   X( LDX, * )
00017 *     ..
00018 *
00019 *  Purpose
00020 *  =======
00021 *
00022 *  ZHBGST reduces a complex Hermitian-definite banded generalized
00023 *  eigenproblem  A*x = lambda*B*x  to standard form  C*y = lambda*y,
00024 *  such that C has the same bandwidth as A.
00025 *
00026 *  B must have been previously factorized as S**H*S by ZPBSTF, using a
00027 *  split Cholesky factorization. A is overwritten by C = X**H*A*X, where
00028 *  X = S**(-1)*Q and Q is a unitary matrix chosen to preserve the
00029 *  bandwidth of A.
00030 *
00031 *  Arguments
00032 *  =========
00033 *
00034 *  VECT    (input) CHARACTER*1
00035 *          = 'N':  do not form the transformation matrix X;
00036 *          = 'V':  form X.
00037 *
00038 *  UPLO    (input) CHARACTER*1
00039 *          = 'U':  Upper triangle of A is stored;
00040 *          = 'L':  Lower triangle of A is stored.
00041 *
00042 *  N       (input) INTEGER
00043 *          The order of the matrices A and B.  N >= 0.
00044 *
00045 *  KA      (input) INTEGER
00046 *          The number of superdiagonals of the matrix A if UPLO = 'U',
00047 *          or the number of subdiagonals if UPLO = 'L'.  KA >= 0.
00048 *
00049 *  KB      (input) INTEGER
00050 *          The number of superdiagonals of the matrix B if UPLO = 'U',
00051 *          or the number of subdiagonals if UPLO = 'L'.  KA >= KB >= 0.
00052 *
00053 *  AB      (input/output) COMPLEX*16 array, dimension (LDAB,N)
00054 *          On entry, the upper or lower triangle of the Hermitian band
00055 *          matrix A, stored in the first ka+1 rows of the array.  The
00056 *          j-th column of A is stored in the j-th column of the array AB
00057 *          as follows:
00058 *          if UPLO = 'U', AB(ka+1+i-j,j) = A(i,j) for max(1,j-ka)<=i<=j;
00059 *          if UPLO = 'L', AB(1+i-j,j)    = A(i,j) for j<=i<=min(n,j+ka).
00060 *
00061 *          On exit, the transformed matrix X**H*A*X, stored in the same
00062 *          format as A.
00063 *
00064 *  LDAB    (input) INTEGER
00065 *          The leading dimension of the array AB.  LDAB >= KA+1.
00066 *
00067 *  BB      (input) COMPLEX*16 array, dimension (LDBB,N)
00068 *          The banded factor S from the split Cholesky factorization of
00069 *          B, as returned by ZPBSTF, stored in the first kb+1 rows of
00070 *          the array.
00071 *
00072 *  LDBB    (input) INTEGER
00073 *          The leading dimension of the array BB.  LDBB >= KB+1.
00074 *
00075 *  X       (output) COMPLEX*16 array, dimension (LDX,N)
00076 *          If VECT = 'V', the n-by-n matrix X.
00077 *          If VECT = 'N', the array X is not referenced.
00078 *
00079 *  LDX     (input) INTEGER
00080 *          The leading dimension of the array X.
00081 *          LDX >= max(1,N) if VECT = 'V'; LDX >= 1 otherwise.
00082 *
00083 *  WORK    (workspace) COMPLEX*16 array, dimension (N)
00084 *
00085 *  RWORK   (workspace) DOUBLE PRECISION array, dimension (N)
00086 *
00087 *  INFO    (output) INTEGER
00088 *          = 0:  successful exit
00089 *          < 0:  if INFO = -i, the i-th argument had an illegal value.
00090 *
00091 *  =====================================================================
00092 *
00093 *     .. Parameters ..
00094       COMPLEX*16         CZERO, CONE
00095       DOUBLE PRECISION   ONE
00096       PARAMETER          ( CZERO = ( 0.0D+0, 0.0D+0 ),
00097      $                   CONE = ( 1.0D+0, 0.0D+0 ), ONE = 1.0D+0 )
00098 *     ..
00099 *     .. Local Scalars ..
00100       LOGICAL            UPDATE, UPPER, WANTX
00101       INTEGER            I, I0, I1, I2, INCA, J, J1, J1T, J2, J2T, K,
00102      $                   KA1, KB1, KBT, L, M, NR, NRT, NX
00103       DOUBLE PRECISION   BII
00104       COMPLEX*16         RA, RA1, T
00105 *     ..
00106 *     .. External Functions ..
00107       LOGICAL            LSAME
00108       EXTERNAL           LSAME
00109 *     ..
00110 *     .. External Subroutines ..
00111       EXTERNAL           XERBLA, ZDSCAL, ZGERC, ZGERU, ZLACGV, ZLAR2V,
00112      $                   ZLARGV, ZLARTG, ZLARTV, ZLASET, ZROT
00113 *     ..
00114 *     .. Intrinsic Functions ..
00115       INTRINSIC          DBLE, DCONJG, MAX, MIN
00116 *     ..
00117 *     .. Executable Statements ..
00118 *
00119 *     Test the input parameters
00120 *
00121       WANTX = LSAME( VECT, 'V' )
00122       UPPER = LSAME( UPLO, 'U' )
00123       KA1 = KA + 1
00124       KB1 = KB + 1
00125       INFO = 0
00126       IF( .NOT.WANTX .AND. .NOT.LSAME( VECT, 'N' ) ) THEN
00127          INFO = -1
00128       ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
00129          INFO = -2
00130       ELSE IF( N.LT.0 ) THEN
00131          INFO = -3
00132       ELSE IF( KA.LT.0 ) THEN
00133          INFO = -4
00134       ELSE IF( KB.LT.0 .OR. KB.GT.KA ) THEN
00135          INFO = -5
00136       ELSE IF( LDAB.LT.KA+1 ) THEN
00137          INFO = -7
00138       ELSE IF( LDBB.LT.KB+1 ) THEN
00139          INFO = -9
00140       ELSE IF( LDX.LT.1 .OR. WANTX .AND. LDX.LT.MAX( 1, N ) ) THEN
00141          INFO = -11
00142       END IF
00143       IF( INFO.NE.0 ) THEN
00144          CALL XERBLA( 'ZHBGST', -INFO )
00145          RETURN
00146       END IF
00147 *
00148 *     Quick return if possible
00149 *
00150       IF( N.EQ.0 )
00151      $   RETURN
00152 *
00153       INCA = LDAB*KA1
00154 *
00155 *     Initialize X to the unit matrix, if needed
00156 *
00157       IF( WANTX )
00158      $   CALL ZLASET( 'Full', N, N, CZERO, CONE, X, LDX )
00159 *
00160 *     Set M to the splitting point m. It must be the same value as is
00161 *     used in ZPBSTF. The chosen value allows the arrays WORK and RWORK
00162 *     to be of dimension (N).
00163 *
00164       M = ( N+KB ) / 2
00165 *
00166 *     The routine works in two phases, corresponding to the two halves
00167 *     of the split Cholesky factorization of B as S**H*S where
00168 *
00169 *     S = ( U    )
00170 *         ( M  L )
00171 *
00172 *     with U upper triangular of order m, and L lower triangular of
00173 *     order n-m. S has the same bandwidth as B.
00174 *
00175 *     S is treated as a product of elementary matrices:
00176 *
00177 *     S = S(m)*S(m-1)*...*S(2)*S(1)*S(m+1)*S(m+2)*...*S(n-1)*S(n)
00178 *
00179 *     where S(i) is determined by the i-th row of S.
00180 *
00181 *     In phase 1, the index i takes the values n, n-1, ... , m+1;
00182 *     in phase 2, it takes the values 1, 2, ... , m.
00183 *
00184 *     For each value of i, the current matrix A is updated by forming
00185 *     inv(S(i))**H*A*inv(S(i)). This creates a triangular bulge outside
00186 *     the band of A. The bulge is then pushed down toward the bottom of
00187 *     A in phase 1, and up toward the top of A in phase 2, by applying
00188 *     plane rotations.
00189 *
00190 *     There are kb*(kb+1)/2 elements in the bulge, but at most 2*kb-1
00191 *     of them are linearly independent, so annihilating a bulge requires
00192 *     only 2*kb-1 plane rotations. The rotations are divided into a 1st
00193 *     set of kb-1 rotations, and a 2nd set of kb rotations.
00194 *
00195 *     Wherever possible, rotations are generated and applied in vector
00196 *     operations of length NR between the indices J1 and J2 (sometimes
00197 *     replaced by modified values NRT, J1T or J2T).
00198 *
00199 *     The real cosines and complex sines of the rotations are stored in
00200 *     the arrays RWORK and WORK, those of the 1st set in elements
00201 *     2:m-kb-1, and those of the 2nd set in elements m-kb+1:n.
00202 *
00203 *     The bulges are not formed explicitly; nonzero elements outside the
00204 *     band are created only when they are required for generating new
00205 *     rotations; they are stored in the array WORK, in positions where
00206 *     they are later overwritten by the sines of the rotations which
00207 *     annihilate them.
00208 *
00209 *     **************************** Phase 1 *****************************
00210 *
00211 *     The logical structure of this phase is:
00212 *
00213 *     UPDATE = .TRUE.
00214 *     DO I = N, M + 1, -1
00215 *        use S(i) to update A and create a new bulge
00216 *        apply rotations to push all bulges KA positions downward
00217 *     END DO
00218 *     UPDATE = .FALSE.
00219 *     DO I = M + KA + 1, N - 1
00220 *        apply rotations to push all bulges KA positions downward
00221 *     END DO
00222 *
00223 *     To avoid duplicating code, the two loops are merged.
00224 *
00225       UPDATE = .TRUE.
00226       I = N + 1
00227    10 CONTINUE
00228       IF( UPDATE ) THEN
00229          I = I - 1
00230          KBT = MIN( KB, I-1 )
00231          I0 = I - 1
00232          I1 = MIN( N, I+KA )
00233          I2 = I - KBT + KA1
00234          IF( I.LT.M+1 ) THEN
00235             UPDATE = .FALSE.
00236             I = I + 1
00237             I0 = M
00238             IF( KA.EQ.0 )
00239      $         GO TO 480
00240             GO TO 10
00241          END IF
00242       ELSE
00243          I = I + KA
00244          IF( I.GT.N-1 )
00245      $      GO TO 480
00246       END IF
00247 *
00248       IF( UPPER ) THEN
00249 *
00250 *        Transform A, working with the upper triangle
00251 *
00252          IF( UPDATE ) THEN
00253 *
00254 *           Form  inv(S(i))**H * A * inv(S(i))
00255 *
00256             BII = DBLE( BB( KB1, I ) )
00257             AB( KA1, I ) = ( DBLE( AB( KA1, I ) ) / BII ) / BII
00258             DO 20 J = I + 1, I1
00259                AB( I-J+KA1, J ) = AB( I-J+KA1, J ) / BII
00260    20       CONTINUE
00261             DO 30 J = MAX( 1, I-KA ), I - 1
00262                AB( J-I+KA1, I ) = AB( J-I+KA1, I ) / BII
00263    30       CONTINUE
00264             DO 60 K = I - KBT, I - 1
00265                DO 40 J = I - KBT, K
00266                   AB( J-K+KA1, K ) = AB( J-K+KA1, K ) -
00267      $                               BB( J-I+KB1, I )*
00268      $                               DCONJG( AB( K-I+KA1, I ) ) -
00269      $                               DCONJG( BB( K-I+KB1, I ) )*
00270      $                               AB( J-I+KA1, I ) +
00271      $                               DBLE( AB( KA1, I ) )*
00272      $                               BB( J-I+KB1, I )*
00273      $                               DCONJG( BB( K-I+KB1, I ) )
00274    40          CONTINUE
00275                DO 50 J = MAX( 1, I-KA ), I - KBT - 1
00276                   AB( J-K+KA1, K ) = AB( J-K+KA1, K ) -
00277      $                               DCONJG( BB( K-I+KB1, I ) )*
00278      $                               AB( J-I+KA1, I )
00279    50          CONTINUE
00280    60       CONTINUE
00281             DO 80 J = I, I1
00282                DO 70 K = MAX( J-KA, I-KBT ), I - 1
00283                   AB( K-J+KA1, J ) = AB( K-J+KA1, J ) -
00284      $                               BB( K-I+KB1, I )*AB( I-J+KA1, J )
00285    70          CONTINUE
00286    80       CONTINUE
00287 *
00288             IF( WANTX ) THEN
00289 *
00290 *              post-multiply X by inv(S(i))
00291 *
00292                CALL ZDSCAL( N-M, ONE / BII, X( M+1, I ), 1 )
00293                IF( KBT.GT.0 )
00294      $            CALL ZGERC( N-M, KBT, -CONE, X( M+1, I ), 1,
00295      $                        BB( KB1-KBT, I ), 1, X( M+1, I-KBT ),
00296      $                        LDX )
00297             END IF
00298 *
00299 *           store a(i,i1) in RA1 for use in next loop over K
00300 *
00301             RA1 = AB( I-I1+KA1, I1 )
00302          END IF
00303 *
00304 *        Generate and apply vectors of rotations to chase all the
00305 *        existing bulges KA positions down toward the bottom of the
00306 *        band
00307 *
00308          DO 130 K = 1, KB - 1
00309             IF( UPDATE ) THEN
00310 *
00311 *              Determine the rotations which would annihilate the bulge
00312 *              which has in theory just been created
00313 *
00314                IF( I-K+KA.LT.N .AND. I-K.GT.1 ) THEN
00315 *
00316 *                 generate rotation to annihilate a(i,i-k+ka+1)
00317 *
00318                   CALL ZLARTG( AB( K+1, I-K+KA ), RA1,
00319      $                         RWORK( I-K+KA-M ), WORK( I-K+KA-M ), RA )
00320 *
00321 *                 create nonzero element a(i-k,i-k+ka+1) outside the
00322 *                 band and store it in WORK(i-k)
00323 *
00324                   T = -BB( KB1-K, I )*RA1
00325                   WORK( I-K ) = RWORK( I-K+KA-M )*T -
00326      $                          DCONJG( WORK( I-K+KA-M ) )*
00327      $                          AB( 1, I-K+KA )
00328                   AB( 1, I-K+KA ) = WORK( I-K+KA-M )*T +
00329      $                              RWORK( I-K+KA-M )*AB( 1, I-K+KA )
00330                   RA1 = RA
00331                END IF
00332             END IF
00333             J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1
00334             NR = ( N-J2+KA ) / KA1
00335             J1 = J2 + ( NR-1 )*KA1
00336             IF( UPDATE ) THEN
00337                J2T = MAX( J2, I+2*KA-K+1 )
00338             ELSE
00339                J2T = J2
00340             END IF
00341             NRT = ( N-J2T+KA ) / KA1
00342             DO 90 J = J2T, J1, KA1
00343 *
00344 *              create nonzero element a(j-ka,j+1) outside the band
00345 *              and store it in WORK(j-m)
00346 *
00347                WORK( J-M ) = WORK( J-M )*AB( 1, J+1 )
00348                AB( 1, J+1 ) = RWORK( J-M )*AB( 1, J+1 )
00349    90       CONTINUE
00350 *
00351 *           generate rotations in 1st set to annihilate elements which
00352 *           have been created outside the band
00353 *
00354             IF( NRT.GT.0 )
00355      $         CALL ZLARGV( NRT, AB( 1, J2T ), INCA, WORK( J2T-M ), KA1,
00356      $                      RWORK( J2T-M ), KA1 )
00357             IF( NR.GT.0 ) THEN
00358 *
00359 *              apply rotations in 1st set from the right
00360 *
00361                DO 100 L = 1, KA - 1
00362                   CALL ZLARTV( NR, AB( KA1-L, J2 ), INCA,
00363      $                         AB( KA-L, J2+1 ), INCA, RWORK( J2-M ),
00364      $                         WORK( J2-M ), KA1 )
00365   100          CONTINUE
00366 *
00367 *              apply rotations in 1st set from both sides to diagonal
00368 *              blocks
00369 *
00370                CALL ZLAR2V( NR, AB( KA1, J2 ), AB( KA1, J2+1 ),
00371      $                      AB( KA, J2+1 ), INCA, RWORK( J2-M ),
00372      $                      WORK( J2-M ), KA1 )
00373 *
00374                CALL ZLACGV( NR, WORK( J2-M ), KA1 )
00375             END IF
00376 *
00377 *           start applying rotations in 1st set from the left
00378 *
00379             DO 110 L = KA - 1, KB - K + 1, -1
00380                NRT = ( N-J2+L ) / KA1
00381                IF( NRT.GT.0 )
00382      $            CALL ZLARTV( NRT, AB( L, J2+KA1-L ), INCA,
00383      $                         AB( L+1, J2+KA1-L ), INCA, RWORK( J2-M ),
00384      $                         WORK( J2-M ), KA1 )
00385   110       CONTINUE
00386 *
00387             IF( WANTX ) THEN
00388 *
00389 *              post-multiply X by product of rotations in 1st set
00390 *
00391                DO 120 J = J2, J1, KA1
00392                   CALL ZROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1,
00393      $                       RWORK( J-M ), DCONJG( WORK( J-M ) ) )
00394   120          CONTINUE
00395             END IF
00396   130    CONTINUE
00397 *
00398          IF( UPDATE ) THEN
00399             IF( I2.LE.N .AND. KBT.GT.0 ) THEN
00400 *
00401 *              create nonzero element a(i-kbt,i-kbt+ka+1) outside the
00402 *              band and store it in WORK(i-kbt)
00403 *
00404                WORK( I-KBT ) = -BB( KB1-KBT, I )*RA1
00405             END IF
00406          END IF
00407 *
00408          DO 170 K = KB, 1, -1
00409             IF( UPDATE ) THEN
00410                J2 = I - K - 1 + MAX( 2, K-I0+1 )*KA1
00411             ELSE
00412                J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1
00413             END IF
00414 *
00415 *           finish applying rotations in 2nd set from the left
00416 *
00417             DO 140 L = KB - K, 1, -1
00418                NRT = ( N-J2+KA+L ) / KA1
00419                IF( NRT.GT.0 )
00420      $            CALL ZLARTV( NRT, AB( L, J2-L+1 ), INCA,
00421      $                         AB( L+1, J2-L+1 ), INCA, RWORK( J2-KA ),
00422      $                         WORK( J2-KA ), KA1 )
00423   140       CONTINUE
00424             NR = ( N-J2+KA ) / KA1
00425             J1 = J2 + ( NR-1 )*KA1
00426             DO 150 J = J1, J2, -KA1
00427                WORK( J ) = WORK( J-KA )
00428                RWORK( J ) = RWORK( J-KA )
00429   150       CONTINUE
00430             DO 160 J = J2, J1, KA1
00431 *
00432 *              create nonzero element a(j-ka,j+1) outside the band
00433 *              and store it in WORK(j)
00434 *
00435                WORK( J ) = WORK( J )*AB( 1, J+1 )
00436                AB( 1, J+1 ) = RWORK( J )*AB( 1, J+1 )
00437   160       CONTINUE
00438             IF( UPDATE ) THEN
00439                IF( I-K.LT.N-KA .AND. K.LE.KBT )
00440      $            WORK( I-K+KA ) = WORK( I-K )
00441             END IF
00442   170    CONTINUE
00443 *
00444          DO 210 K = KB, 1, -1
00445             J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1
00446             NR = ( N-J2+KA ) / KA1
00447             J1 = J2 + ( NR-1 )*KA1
00448             IF( NR.GT.0 ) THEN
00449 *
00450 *              generate rotations in 2nd set to annihilate elements
00451 *              which have been created outside the band
00452 *
00453                CALL ZLARGV( NR, AB( 1, J2 ), INCA, WORK( J2 ), KA1,
00454      $                      RWORK( J2 ), KA1 )
00455 *
00456 *              apply rotations in 2nd set from the right
00457 *
00458                DO 180 L = 1, KA - 1
00459                   CALL ZLARTV( NR, AB( KA1-L, J2 ), INCA,
00460      $                         AB( KA-L, J2+1 ), INCA, RWORK( J2 ),
00461      $                         WORK( J2 ), KA1 )
00462   180          CONTINUE
00463 *
00464 *              apply rotations in 2nd set from both sides to diagonal
00465 *              blocks
00466 *
00467                CALL ZLAR2V( NR, AB( KA1, J2 ), AB( KA1, J2+1 ),
00468      $                      AB( KA, J2+1 ), INCA, RWORK( J2 ),
00469      $                      WORK( J2 ), KA1 )
00470 *
00471                CALL ZLACGV( NR, WORK( J2 ), KA1 )
00472             END IF
00473 *
00474 *           start applying rotations in 2nd set from the left
00475 *
00476             DO 190 L = KA - 1, KB - K + 1, -1
00477                NRT = ( N-J2+L ) / KA1
00478                IF( NRT.GT.0 )
00479      $            CALL ZLARTV( NRT, AB( L, J2+KA1-L ), INCA,
00480      $                         AB( L+1, J2+KA1-L ), INCA, RWORK( J2 ),
00481      $                         WORK( J2 ), KA1 )
00482   190       CONTINUE
00483 *
00484             IF( WANTX ) THEN
00485 *
00486 *              post-multiply X by product of rotations in 2nd set
00487 *
00488                DO 200 J = J2, J1, KA1
00489                   CALL ZROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1,
00490      $                       RWORK( J ), DCONJG( WORK( J ) ) )
00491   200          CONTINUE
00492             END IF
00493   210    CONTINUE
00494 *
00495          DO 230 K = 1, KB - 1
00496             J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1
00497 *
00498 *           finish applying rotations in 1st set from the left
00499 *
00500             DO 220 L = KB - K, 1, -1
00501                NRT = ( N-J2+L ) / KA1
00502                IF( NRT.GT.0 )
00503      $            CALL ZLARTV( NRT, AB( L, J2+KA1-L ), INCA,
00504      $                         AB( L+1, J2+KA1-L ), INCA, RWORK( J2-M ),
00505      $                         WORK( J2-M ), KA1 )
00506   220       CONTINUE
00507   230    CONTINUE
00508 *
00509          IF( KB.GT.1 ) THEN
00510             DO 240 J = N - 1, J2 + KA, -1
00511                RWORK( J-M ) = RWORK( J-KA-M )
00512                WORK( J-M ) = WORK( J-KA-M )
00513   240       CONTINUE
00514          END IF
00515 *
00516       ELSE
00517 *
00518 *        Transform A, working with the lower triangle
00519 *
00520          IF( UPDATE ) THEN
00521 *
00522 *           Form  inv(S(i))**H * A * inv(S(i))
00523 *
00524             BII = DBLE( BB( 1, I ) )
00525             AB( 1, I ) = ( DBLE( AB( 1, I ) ) / BII ) / BII
00526             DO 250 J = I + 1, I1
00527                AB( J-I+1, I ) = AB( J-I+1, I ) / BII
00528   250       CONTINUE
00529             DO 260 J = MAX( 1, I-KA ), I - 1
00530                AB( I-J+1, J ) = AB( I-J+1, J ) / BII
00531   260       CONTINUE
00532             DO 290 K = I - KBT, I - 1
00533                DO 270 J = I - KBT, K
00534                   AB( K-J+1, J ) = AB( K-J+1, J ) -
00535      $                             BB( I-J+1, J )*DCONJG( AB( I-K+1,
00536      $                             K ) ) - DCONJG( BB( I-K+1, K ) )*
00537      $                             AB( I-J+1, J ) + DBLE( AB( 1, I ) )*
00538      $                             BB( I-J+1, J )*DCONJG( BB( I-K+1,
00539      $                             K ) )
00540   270          CONTINUE
00541                DO 280 J = MAX( 1, I-KA ), I - KBT - 1
00542                   AB( K-J+1, J ) = AB( K-J+1, J ) -
00543      $                             DCONJG( BB( I-K+1, K ) )*
00544      $                             AB( I-J+1, J )
00545   280          CONTINUE
00546   290       CONTINUE
00547             DO 310 J = I, I1
00548                DO 300 K = MAX( J-KA, I-KBT ), I - 1
00549                   AB( J-K+1, K ) = AB( J-K+1, K ) -
00550      $                             BB( I-K+1, K )*AB( J-I+1, I )
00551   300          CONTINUE
00552   310       CONTINUE
00553 *
00554             IF( WANTX ) THEN
00555 *
00556 *              post-multiply X by inv(S(i))
00557 *
00558                CALL ZDSCAL( N-M, ONE / BII, X( M+1, I ), 1 )
00559                IF( KBT.GT.0 )
00560      $            CALL ZGERU( N-M, KBT, -CONE, X( M+1, I ), 1,
00561      $                        BB( KBT+1, I-KBT ), LDBB-1,
00562      $                        X( M+1, I-KBT ), LDX )
00563             END IF
00564 *
00565 *           store a(i1,i) in RA1 for use in next loop over K
00566 *
00567             RA1 = AB( I1-I+1, I )
00568          END IF
00569 *
00570 *        Generate and apply vectors of rotations to chase all the
00571 *        existing bulges KA positions down toward the bottom of the
00572 *        band
00573 *
00574          DO 360 K = 1, KB - 1
00575             IF( UPDATE ) THEN
00576 *
00577 *              Determine the rotations which would annihilate the bulge
00578 *              which has in theory just been created
00579 *
00580                IF( I-K+KA.LT.N .AND. I-K.GT.1 ) THEN
00581 *
00582 *                 generate rotation to annihilate a(i-k+ka+1,i)
00583 *
00584                   CALL ZLARTG( AB( KA1-K, I ), RA1, RWORK( I-K+KA-M ),
00585      $                         WORK( I-K+KA-M ), RA )
00586 *
00587 *                 create nonzero element a(i-k+ka+1,i-k) outside the
00588 *                 band and store it in WORK(i-k)
00589 *
00590                   T = -BB( K+1, I-K )*RA1
00591                   WORK( I-K ) = RWORK( I-K+KA-M )*T -
00592      $                          DCONJG( WORK( I-K+KA-M ) )*
00593      $                          AB( KA1, I-K )
00594                   AB( KA1, I-K ) = WORK( I-K+KA-M )*T +
00595      $                             RWORK( I-K+KA-M )*AB( KA1, I-K )
00596                   RA1 = RA
00597                END IF
00598             END IF
00599             J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1
00600             NR = ( N-J2+KA ) / KA1
00601             J1 = J2 + ( NR-1 )*KA1
00602             IF( UPDATE ) THEN
00603                J2T = MAX( J2, I+2*KA-K+1 )
00604             ELSE
00605                J2T = J2
00606             END IF
00607             NRT = ( N-J2T+KA ) / KA1
00608             DO 320 J = J2T, J1, KA1
00609 *
00610 *              create nonzero element a(j+1,j-ka) outside the band
00611 *              and store it in WORK(j-m)
00612 *
00613                WORK( J-M ) = WORK( J-M )*AB( KA1, J-KA+1 )
00614                AB( KA1, J-KA+1 ) = RWORK( J-M )*AB( KA1, J-KA+1 )
00615   320       CONTINUE
00616 *
00617 *           generate rotations in 1st set to annihilate elements which
00618 *           have been created outside the band
00619 *
00620             IF( NRT.GT.0 )
00621      $         CALL ZLARGV( NRT, AB( KA1, J2T-KA ), INCA, WORK( J2T-M ),
00622      $                      KA1, RWORK( J2T-M ), KA1 )
00623             IF( NR.GT.0 ) THEN
00624 *
00625 *              apply rotations in 1st set from the left
00626 *
00627                DO 330 L = 1, KA - 1
00628                   CALL ZLARTV( NR, AB( L+1, J2-L ), INCA,
00629      $                         AB( L+2, J2-L ), INCA, RWORK( J2-M ),
00630      $                         WORK( J2-M ), KA1 )
00631   330          CONTINUE
00632 *
00633 *              apply rotations in 1st set from both sides to diagonal
00634 *              blocks
00635 *
00636                CALL ZLAR2V( NR, AB( 1, J2 ), AB( 1, J2+1 ), AB( 2, J2 ),
00637      $                      INCA, RWORK( J2-M ), WORK( J2-M ), KA1 )
00638 *
00639                CALL ZLACGV( NR, WORK( J2-M ), KA1 )
00640             END IF
00641 *
00642 *           start applying rotations in 1st set from the right
00643 *
00644             DO 340 L = KA - 1, KB - K + 1, -1
00645                NRT = ( N-J2+L ) / KA1
00646                IF( NRT.GT.0 )
00647      $            CALL ZLARTV( NRT, AB( KA1-L+1, J2 ), INCA,
00648      $                         AB( KA1-L, J2+1 ), INCA, RWORK( J2-M ),
00649      $                         WORK( J2-M ), KA1 )
00650   340       CONTINUE
00651 *
00652             IF( WANTX ) THEN
00653 *
00654 *              post-multiply X by product of rotations in 1st set
00655 *
00656                DO 350 J = J2, J1, KA1
00657                   CALL ZROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1,
00658      $                       RWORK( J-M ), WORK( J-M ) )
00659   350          CONTINUE
00660             END IF
00661   360    CONTINUE
00662 *
00663          IF( UPDATE ) THEN
00664             IF( I2.LE.N .AND. KBT.GT.0 ) THEN
00665 *
00666 *              create nonzero element a(i-kbt+ka+1,i-kbt) outside the
00667 *              band and store it in WORK(i-kbt)
00668 *
00669                WORK( I-KBT ) = -BB( KBT+1, I-KBT )*RA1
00670             END IF
00671          END IF
00672 *
00673          DO 400 K = KB, 1, -1
00674             IF( UPDATE ) THEN
00675                J2 = I - K - 1 + MAX( 2, K-I0+1 )*KA1
00676             ELSE
00677                J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1
00678             END IF
00679 *
00680 *           finish applying rotations in 2nd set from the right
00681 *
00682             DO 370 L = KB - K, 1, -1
00683                NRT = ( N-J2+KA+L ) / KA1
00684                IF( NRT.GT.0 )
00685      $            CALL ZLARTV( NRT, AB( KA1-L+1, J2-KA ), INCA,
00686      $                         AB( KA1-L, J2-KA+1 ), INCA,
00687      $                         RWORK( J2-KA ), WORK( J2-KA ), KA1 )
00688   370       CONTINUE
00689             NR = ( N-J2+KA ) / KA1
00690             J1 = J2 + ( NR-1 )*KA1
00691             DO 380 J = J1, J2, -KA1
00692                WORK( J ) = WORK( J-KA )
00693                RWORK( J ) = RWORK( J-KA )
00694   380       CONTINUE
00695             DO 390 J = J2, J1, KA1
00696 *
00697 *              create nonzero element a(j+1,j-ka) outside the band
00698 *              and store it in WORK(j)
00699 *
00700                WORK( J ) = WORK( J )*AB( KA1, J-KA+1 )
00701                AB( KA1, J-KA+1 ) = RWORK( J )*AB( KA1, J-KA+1 )
00702   390       CONTINUE
00703             IF( UPDATE ) THEN
00704                IF( I-K.LT.N-KA .AND. K.LE.KBT )
00705      $            WORK( I-K+KA ) = WORK( I-K )
00706             END IF
00707   400    CONTINUE
00708 *
00709          DO 440 K = KB, 1, -1
00710             J2 = I - K - 1 + MAX( 1, K-I0+1 )*KA1
00711             NR = ( N-J2+KA ) / KA1
00712             J1 = J2 + ( NR-1 )*KA1
00713             IF( NR.GT.0 ) THEN
00714 *
00715 *              generate rotations in 2nd set to annihilate elements
00716 *              which have been created outside the band
00717 *
00718                CALL ZLARGV( NR, AB( KA1, J2-KA ), INCA, WORK( J2 ), KA1,
00719      $                      RWORK( J2 ), KA1 )
00720 *
00721 *              apply rotations in 2nd set from the left
00722 *
00723                DO 410 L = 1, KA - 1
00724                   CALL ZLARTV( NR, AB( L+1, J2-L ), INCA,
00725      $                         AB( L+2, J2-L ), INCA, RWORK( J2 ),
00726      $                         WORK( J2 ), KA1 )
00727   410          CONTINUE
00728 *
00729 *              apply rotations in 2nd set from both sides to diagonal
00730 *              blocks
00731 *
00732                CALL ZLAR2V( NR, AB( 1, J2 ), AB( 1, J2+1 ), AB( 2, J2 ),
00733      $                      INCA, RWORK( J2 ), WORK( J2 ), KA1 )
00734 *
00735                CALL ZLACGV( NR, WORK( J2 ), KA1 )
00736             END IF
00737 *
00738 *           start applying rotations in 2nd set from the right
00739 *
00740             DO 420 L = KA - 1, KB - K + 1, -1
00741                NRT = ( N-J2+L ) / KA1
00742                IF( NRT.GT.0 )
00743      $            CALL ZLARTV( NRT, AB( KA1-L+1, J2 ), INCA,
00744      $                         AB( KA1-L, J2+1 ), INCA, RWORK( J2 ),
00745      $                         WORK( J2 ), KA1 )
00746   420       CONTINUE
00747 *
00748             IF( WANTX ) THEN
00749 *
00750 *              post-multiply X by product of rotations in 2nd set
00751 *
00752                DO 430 J = J2, J1, KA1
00753                   CALL ZROT( N-M, X( M+1, J ), 1, X( M+1, J+1 ), 1,
00754      $                       RWORK( J ), WORK( J ) )
00755   430          CONTINUE
00756             END IF
00757   440    CONTINUE
00758 *
00759          DO 460 K = 1, KB - 1
00760             J2 = I - K - 1 + MAX( 1, K-I0+2 )*KA1
00761 *
00762 *           finish applying rotations in 1st set from the right
00763 *
00764             DO 450 L = KB - K, 1, -1
00765                NRT = ( N-J2+L ) / KA1
00766                IF( NRT.GT.0 )
00767      $            CALL ZLARTV( NRT, AB( KA1-L+1, J2 ), INCA,
00768      $                         AB( KA1-L, J2+1 ), INCA, RWORK( J2-M ),
00769      $                         WORK( J2-M ), KA1 )
00770   450       CONTINUE
00771   460    CONTINUE
00772 *
00773          IF( KB.GT.1 ) THEN
00774             DO 470 J = N - 1, J2 + KA, -1
00775                RWORK( J-M ) = RWORK( J-KA-M )
00776                WORK( J-M ) = WORK( J-KA-M )
00777   470       CONTINUE
00778          END IF
00779 *
00780       END IF
00781 *
00782       GO TO 10
00783 *
00784   480 CONTINUE
00785 *
00786 *     **************************** Phase 2 *****************************
00787 *
00788 *     The logical structure of this phase is:
00789 *
00790 *     UPDATE = .TRUE.
00791 *     DO I = 1, M
00792 *        use S(i) to update A and create a new bulge
00793 *        apply rotations to push all bulges KA positions upward
00794 *     END DO
00795 *     UPDATE = .FALSE.
00796 *     DO I = M - KA - 1, 2, -1
00797 *        apply rotations to push all bulges KA positions upward
00798 *     END DO
00799 *
00800 *     To avoid duplicating code, the two loops are merged.
00801 *
00802       UPDATE = .TRUE.
00803       I = 0
00804   490 CONTINUE
00805       IF( UPDATE ) THEN
00806          I = I + 1
00807          KBT = MIN( KB, M-I )
00808          I0 = I + 1
00809          I1 = MAX( 1, I-KA )
00810          I2 = I + KBT - KA1
00811          IF( I.GT.M ) THEN
00812             UPDATE = .FALSE.
00813             I = I - 1
00814             I0 = M + 1
00815             IF( KA.EQ.0 )
00816      $         RETURN
00817             GO TO 490
00818          END IF
00819       ELSE
00820          I = I - KA
00821          IF( I.LT.2 )
00822      $      RETURN
00823       END IF
00824 *
00825       IF( I.LT.M-KBT ) THEN
00826          NX = M
00827       ELSE
00828          NX = N
00829       END IF
00830 *
00831       IF( UPPER ) THEN
00832 *
00833 *        Transform A, working with the upper triangle
00834 *
00835          IF( UPDATE ) THEN
00836 *
00837 *           Form  inv(S(i))**H * A * inv(S(i))
00838 *
00839             BII = DBLE( BB( KB1, I ) )
00840             AB( KA1, I ) = ( DBLE( AB( KA1, I ) ) / BII ) / BII
00841             DO 500 J = I1, I - 1
00842                AB( J-I+KA1, I ) = AB( J-I+KA1, I ) / BII
00843   500       CONTINUE
00844             DO 510 J = I + 1, MIN( N, I+KA )
00845                AB( I-J+KA1, J ) = AB( I-J+KA1, J ) / BII
00846   510       CONTINUE
00847             DO 540 K = I + 1, I + KBT
00848                DO 520 J = K, I + KBT
00849                   AB( K-J+KA1, J ) = AB( K-J+KA1, J ) -
00850      $                               BB( I-J+KB1, J )*
00851      $                               DCONJG( AB( I-K+KA1, K ) ) -
00852      $                               DCONJG( BB( I-K+KB1, K ) )*
00853      $                               AB( I-J+KA1, J ) +
00854      $                               DBLE( AB( KA1, I ) )*
00855      $                               BB( I-J+KB1, J )*
00856      $                               DCONJG( BB( I-K+KB1, K ) )
00857   520          CONTINUE
00858                DO 530 J = I + KBT + 1, MIN( N, I+KA )
00859                   AB( K-J+KA1, J ) = AB( K-J+KA1, J ) -
00860      $                               DCONJG( BB( I-K+KB1, K ) )*
00861      $                               AB( I-J+KA1, J )
00862   530          CONTINUE
00863   540       CONTINUE
00864             DO 560 J = I1, I
00865                DO 550 K = I + 1, MIN( J+KA, I+KBT )
00866                   AB( J-K+KA1, K ) = AB( J-K+KA1, K ) -
00867      $                               BB( I-K+KB1, K )*AB( J-I+KA1, I )
00868   550          CONTINUE
00869   560       CONTINUE
00870 *
00871             IF( WANTX ) THEN
00872 *
00873 *              post-multiply X by inv(S(i))
00874 *
00875                CALL ZDSCAL( NX, ONE / BII, X( 1, I ), 1 )
00876                IF( KBT.GT.0 )
00877      $            CALL ZGERU( NX, KBT, -CONE, X( 1, I ), 1,
00878      $                        BB( KB, I+1 ), LDBB-1, X( 1, I+1 ), LDX )
00879             END IF
00880 *
00881 *           store a(i1,i) in RA1 for use in next loop over K
00882 *
00883             RA1 = AB( I1-I+KA1, I )
00884          END IF
00885 *
00886 *        Generate and apply vectors of rotations to chase all the
00887 *        existing bulges KA positions up toward the top of the band
00888 *
00889          DO 610 K = 1, KB - 1
00890             IF( UPDATE ) THEN
00891 *
00892 *              Determine the rotations which would annihilate the bulge
00893 *              which has in theory just been created
00894 *
00895                IF( I+K-KA1.GT.0 .AND. I+K.LT.M ) THEN
00896 *
00897 *                 generate rotation to annihilate a(i+k-ka-1,i)
00898 *
00899                   CALL ZLARTG( AB( K+1, I ), RA1, RWORK( I+K-KA ),
00900      $                         WORK( I+K-KA ), RA )
00901 *
00902 *                 create nonzero element a(i+k-ka-1,i+k) outside the
00903 *                 band and store it in WORK(m-kb+i+k)
00904 *
00905                   T = -BB( KB1-K, I+K )*RA1
00906                   WORK( M-KB+I+K ) = RWORK( I+K-KA )*T -
00907      $                               DCONJG( WORK( I+K-KA ) )*
00908      $                               AB( 1, I+K )
00909                   AB( 1, I+K ) = WORK( I+K-KA )*T +
00910      $                           RWORK( I+K-KA )*AB( 1, I+K )
00911                   RA1 = RA
00912                END IF
00913             END IF
00914             J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1
00915             NR = ( J2+KA-1 ) / KA1
00916             J1 = J2 - ( NR-1 )*KA1
00917             IF( UPDATE ) THEN
00918                J2T = MIN( J2, I-2*KA+K-1 )
00919             ELSE
00920                J2T = J2
00921             END IF
00922             NRT = ( J2T+KA-1 ) / KA1
00923             DO 570 J = J1, J2T, KA1
00924 *
00925 *              create nonzero element a(j-1,j+ka) outside the band
00926 *              and store it in WORK(j)
00927 *
00928                WORK( J ) = WORK( J )*AB( 1, J+KA-1 )
00929                AB( 1, J+KA-1 ) = RWORK( J )*AB( 1, J+KA-1 )
00930   570       CONTINUE
00931 *
00932 *           generate rotations in 1st set to annihilate elements which
00933 *           have been created outside the band
00934 *
00935             IF( NRT.GT.0 )
00936      $         CALL ZLARGV( NRT, AB( 1, J1+KA ), INCA, WORK( J1 ), KA1,
00937      $                      RWORK( J1 ), KA1 )
00938             IF( NR.GT.0 ) THEN
00939 *
00940 *              apply rotations in 1st set from the left
00941 *
00942                DO 580 L = 1, KA - 1
00943                   CALL ZLARTV( NR, AB( KA1-L, J1+L ), INCA,
00944      $                         AB( KA-L, J1+L ), INCA, RWORK( J1 ),
00945      $                         WORK( J1 ), KA1 )
00946   580          CONTINUE
00947 *
00948 *              apply rotations in 1st set from both sides to diagonal
00949 *              blocks
00950 *
00951                CALL ZLAR2V( NR, AB( KA1, J1 ), AB( KA1, J1-1 ),
00952      $                      AB( KA, J1 ), INCA, RWORK( J1 ), WORK( J1 ),
00953      $                      KA1 )
00954 *
00955                CALL ZLACGV( NR, WORK( J1 ), KA1 )
00956             END IF
00957 *
00958 *           start applying rotations in 1st set from the right
00959 *
00960             DO 590 L = KA - 1, KB - K + 1, -1
00961                NRT = ( J2+L-1 ) / KA1
00962                J1T = J2 - ( NRT-1 )*KA1
00963                IF( NRT.GT.0 )
00964      $            CALL ZLARTV( NRT, AB( L, J1T ), INCA,
00965      $                         AB( L+1, J1T-1 ), INCA, RWORK( J1T ),
00966      $                         WORK( J1T ), KA1 )
00967   590       CONTINUE
00968 *
00969             IF( WANTX ) THEN
00970 *
00971 *              post-multiply X by product of rotations in 1st set
00972 *
00973                DO 600 J = J1, J2, KA1
00974                   CALL ZROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1,
00975      $                       RWORK( J ), WORK( J ) )
00976   600          CONTINUE
00977             END IF
00978   610    CONTINUE
00979 *
00980          IF( UPDATE ) THEN
00981             IF( I2.GT.0 .AND. KBT.GT.0 ) THEN
00982 *
00983 *              create nonzero element a(i+kbt-ka-1,i+kbt) outside the
00984 *              band and store it in WORK(m-kb+i+kbt)
00985 *
00986                WORK( M-KB+I+KBT ) = -BB( KB1-KBT, I+KBT )*RA1
00987             END IF
00988          END IF
00989 *
00990          DO 650 K = KB, 1, -1
00991             IF( UPDATE ) THEN
00992                J2 = I + K + 1 - MAX( 2, K+I0-M )*KA1
00993             ELSE
00994                J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1
00995             END IF
00996 *
00997 *           finish applying rotations in 2nd set from the right
00998 *
00999             DO 620 L = KB - K, 1, -1
01000                NRT = ( J2+KA+L-1 ) / KA1
01001                J1T = J2 - ( NRT-1 )*KA1
01002                IF( NRT.GT.0 )
01003      $            CALL ZLARTV( NRT, AB( L, J1T+KA ), INCA,
01004      $                         AB( L+1, J1T+KA-1 ), INCA,
01005      $                         RWORK( M-KB+J1T+KA ),
01006      $                         WORK( M-KB+J1T+KA ), KA1 )
01007   620       CONTINUE
01008             NR = ( J2+KA-1 ) / KA1
01009             J1 = J2 - ( NR-1 )*KA1
01010             DO 630 J = J1, J2, KA1
01011                WORK( M-KB+J ) = WORK( M-KB+J+KA )
01012                RWORK( M-KB+J ) = RWORK( M-KB+J+KA )
01013   630       CONTINUE
01014             DO 640 J = J1, J2, KA1
01015 *
01016 *              create nonzero element a(j-1,j+ka) outside the band
01017 *              and store it in WORK(m-kb+j)
01018 *
01019                WORK( M-KB+J ) = WORK( M-KB+J )*AB( 1, J+KA-1 )
01020                AB( 1, J+KA-1 ) = RWORK( M-KB+J )*AB( 1, J+KA-1 )
01021   640       CONTINUE
01022             IF( UPDATE ) THEN
01023                IF( I+K.GT.KA1 .AND. K.LE.KBT )
01024      $            WORK( M-KB+I+K-KA ) = WORK( M-KB+I+K )
01025             END IF
01026   650    CONTINUE
01027 *
01028          DO 690 K = KB, 1, -1
01029             J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1
01030             NR = ( J2+KA-1 ) / KA1
01031             J1 = J2 - ( NR-1 )*KA1
01032             IF( NR.GT.0 ) THEN
01033 *
01034 *              generate rotations in 2nd set to annihilate elements
01035 *              which have been created outside the band
01036 *
01037                CALL ZLARGV( NR, AB( 1, J1+KA ), INCA, WORK( M-KB+J1 ),
01038      $                      KA1, RWORK( M-KB+J1 ), KA1 )
01039 *
01040 *              apply rotations in 2nd set from the left
01041 *
01042                DO 660 L = 1, KA - 1
01043                   CALL ZLARTV( NR, AB( KA1-L, J1+L ), INCA,
01044      $                         AB( KA-L, J1+L ), INCA, RWORK( M-KB+J1 ),
01045      $                         WORK( M-KB+J1 ), KA1 )
01046   660          CONTINUE
01047 *
01048 *              apply rotations in 2nd set from both sides to diagonal
01049 *              blocks
01050 *
01051                CALL ZLAR2V( NR, AB( KA1, J1 ), AB( KA1, J1-1 ),
01052      $                      AB( KA, J1 ), INCA, RWORK( M-KB+J1 ),
01053      $                      WORK( M-KB+J1 ), KA1 )
01054 *
01055                CALL ZLACGV( NR, WORK( M-KB+J1 ), KA1 )
01056             END IF
01057 *
01058 *           start applying rotations in 2nd set from the right
01059 *
01060             DO 670 L = KA - 1, KB - K + 1, -1
01061                NRT = ( J2+L-1 ) / KA1
01062                J1T = J2 - ( NRT-1 )*KA1
01063                IF( NRT.GT.0 )
01064      $            CALL ZLARTV( NRT, AB( L, J1T ), INCA,
01065      $                         AB( L+1, J1T-1 ), INCA,
01066      $                         RWORK( M-KB+J1T ), WORK( M-KB+J1T ),
01067      $                         KA1 )
01068   670       CONTINUE
01069 *
01070             IF( WANTX ) THEN
01071 *
01072 *              post-multiply X by product of rotations in 2nd set
01073 *
01074                DO 680 J = J1, J2, KA1
01075                   CALL ZROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1,
01076      $                       RWORK( M-KB+J ), WORK( M-KB+J ) )
01077   680          CONTINUE
01078             END IF
01079   690    CONTINUE
01080 *
01081          DO 710 K = 1, KB - 1
01082             J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1
01083 *
01084 *           finish applying rotations in 1st set from the right
01085 *
01086             DO 700 L = KB - K, 1, -1
01087                NRT = ( J2+L-1 ) / KA1
01088                J1T = J2 - ( NRT-1 )*KA1
01089                IF( NRT.GT.0 )
01090      $            CALL ZLARTV( NRT, AB( L, J1T ), INCA,
01091      $                         AB( L+1, J1T-1 ), INCA, RWORK( J1T ),
01092      $                         WORK( J1T ), KA1 )
01093   700       CONTINUE
01094   710    CONTINUE
01095 *
01096          IF( KB.GT.1 ) THEN
01097             DO 720 J = 2, I2 - KA
01098                RWORK( J ) = RWORK( J+KA )
01099                WORK( J ) = WORK( J+KA )
01100   720       CONTINUE
01101          END IF
01102 *
01103       ELSE
01104 *
01105 *        Transform A, working with the lower triangle
01106 *
01107          IF( UPDATE ) THEN
01108 *
01109 *           Form  inv(S(i))**H * A * inv(S(i))
01110 *
01111             BII = DBLE( BB( 1, I ) )
01112             AB( 1, I ) = ( DBLE( AB( 1, I ) ) / BII ) / BII
01113             DO 730 J = I1, I - 1
01114                AB( I-J+1, J ) = AB( I-J+1, J ) / BII
01115   730       CONTINUE
01116             DO 740 J = I + 1, MIN( N, I+KA )
01117                AB( J-I+1, I ) = AB( J-I+1, I ) / BII
01118   740       CONTINUE
01119             DO 770 K = I + 1, I + KBT
01120                DO 750 J = K, I + KBT
01121                   AB( J-K+1, K ) = AB( J-K+1, K ) -
01122      $                             BB( J-I+1, I )*DCONJG( AB( K-I+1,
01123      $                             I ) ) - DCONJG( BB( K-I+1, I ) )*
01124      $                             AB( J-I+1, I ) + DBLE( AB( 1, I ) )*
01125      $                             BB( J-I+1, I )*DCONJG( BB( K-I+1,
01126      $                             I ) )
01127   750          CONTINUE
01128                DO 760 J = I + KBT + 1, MIN( N, I+KA )
01129                   AB( J-K+1, K ) = AB( J-K+1, K ) -
01130      $                             DCONJG( BB( K-I+1, I ) )*
01131      $                             AB( J-I+1, I )
01132   760          CONTINUE
01133   770       CONTINUE
01134             DO 790 J = I1, I
01135                DO 780 K = I + 1, MIN( J+KA, I+KBT )
01136                   AB( K-J+1, J ) = AB( K-J+1, J ) -
01137      $                             BB( K-I+1, I )*AB( I-J+1, J )
01138   780          CONTINUE
01139   790       CONTINUE
01140 *
01141             IF( WANTX ) THEN
01142 *
01143 *              post-multiply X by inv(S(i))
01144 *
01145                CALL ZDSCAL( NX, ONE / BII, X( 1, I ), 1 )
01146                IF( KBT.GT.0 )
01147      $            CALL ZGERC( NX, KBT, -CONE, X( 1, I ), 1, BB( 2, I ),
01148      $                        1, X( 1, I+1 ), LDX )
01149             END IF
01150 *
01151 *           store a(i,i1) in RA1 for use in next loop over K
01152 *
01153             RA1 = AB( I-I1+1, I1 )
01154          END IF
01155 *
01156 *        Generate and apply vectors of rotations to chase all the
01157 *        existing bulges KA positions up toward the top of the band
01158 *
01159          DO 840 K = 1, KB - 1
01160             IF( UPDATE ) THEN
01161 *
01162 *              Determine the rotations which would annihilate the bulge
01163 *              which has in theory just been created
01164 *
01165                IF( I+K-KA1.GT.0 .AND. I+K.LT.M ) THEN
01166 *
01167 *                 generate rotation to annihilate a(i,i+k-ka-1)
01168 *
01169                   CALL ZLARTG( AB( KA1-K, I+K-KA ), RA1,
01170      $                         RWORK( I+K-KA ), WORK( I+K-KA ), RA )
01171 *
01172 *                 create nonzero element a(i+k,i+k-ka-1) outside the
01173 *                 band and store it in WORK(m-kb+i+k)
01174 *
01175                   T = -BB( K+1, I )*RA1
01176                   WORK( M-KB+I+K ) = RWORK( I+K-KA )*T -
01177      $                               DCONJG( WORK( I+K-KA ) )*
01178      $                               AB( KA1, I+K-KA )
01179                   AB( KA1, I+K-KA ) = WORK( I+K-KA )*T +
01180      $                                RWORK( I+K-KA )*AB( KA1, I+K-KA )
01181                   RA1 = RA
01182                END IF
01183             END IF
01184             J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1
01185             NR = ( J2+KA-1 ) / KA1
01186             J1 = J2 - ( NR-1 )*KA1
01187             IF( UPDATE ) THEN
01188                J2T = MIN( J2, I-2*KA+K-1 )
01189             ELSE
01190                J2T = J2
01191             END IF
01192             NRT = ( J2T+KA-1 ) / KA1
01193             DO 800 J = J1, J2T, KA1
01194 *
01195 *              create nonzero element a(j+ka,j-1) outside the band
01196 *              and store it in WORK(j)
01197 *
01198                WORK( J ) = WORK( J )*AB( KA1, J-1 )
01199                AB( KA1, J-1 ) = RWORK( J )*AB( KA1, J-1 )
01200   800       CONTINUE
01201 *
01202 *           generate rotations in 1st set to annihilate elements which
01203 *           have been created outside the band
01204 *
01205             IF( NRT.GT.0 )
01206      $         CALL ZLARGV( NRT, AB( KA1, J1 ), INCA, WORK( J1 ), KA1,
01207      $                      RWORK( J1 ), KA1 )
01208             IF( NR.GT.0 ) THEN
01209 *
01210 *              apply rotations in 1st set from the right
01211 *
01212                DO 810 L = 1, KA - 1
01213                   CALL ZLARTV( NR, AB( L+1, J1 ), INCA, AB( L+2, J1-1 ),
01214      $                         INCA, RWORK( J1 ), WORK( J1 ), KA1 )
01215   810          CONTINUE
01216 *
01217 *              apply rotations in 1st set from both sides to diagonal
01218 *              blocks
01219 *
01220                CALL ZLAR2V( NR, AB( 1, J1 ), AB( 1, J1-1 ),
01221      $                      AB( 2, J1-1 ), INCA, RWORK( J1 ),
01222      $                      WORK( J1 ), KA1 )
01223 *
01224                CALL ZLACGV( NR, WORK( J1 ), KA1 )
01225             END IF
01226 *
01227 *           start applying rotations in 1st set from the left
01228 *
01229             DO 820 L = KA - 1, KB - K + 1, -1
01230                NRT = ( J2+L-1 ) / KA1
01231                J1T = J2 - ( NRT-1 )*KA1
01232                IF( NRT.GT.0 )
01233      $            CALL ZLARTV( NRT, AB( KA1-L+1, J1T-KA1+L ), INCA,
01234      $                         AB( KA1-L, J1T-KA1+L ), INCA,
01235      $                         RWORK( J1T ), WORK( J1T ), KA1 )
01236   820       CONTINUE
01237 *
01238             IF( WANTX ) THEN
01239 *
01240 *              post-multiply X by product of rotations in 1st set
01241 *
01242                DO 830 J = J1, J2, KA1
01243                   CALL ZROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1,
01244      $                       RWORK( J ), DCONJG( WORK( J ) ) )
01245   830          CONTINUE
01246             END IF
01247   840    CONTINUE
01248 *
01249          IF( UPDATE ) THEN
01250             IF( I2.GT.0 .AND. KBT.GT.0 ) THEN
01251 *
01252 *              create nonzero element a(i+kbt,i+kbt-ka-1) outside the
01253 *              band and store it in WORK(m-kb+i+kbt)
01254 *
01255                WORK( M-KB+I+KBT ) = -BB( KBT+1, I )*RA1
01256             END IF
01257          END IF
01258 *
01259          DO 880 K = KB, 1, -1
01260             IF( UPDATE ) THEN
01261                J2 = I + K + 1 - MAX( 2, K+I0-M )*KA1
01262             ELSE
01263                J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1
01264             END IF
01265 *
01266 *           finish applying rotations in 2nd set from the left
01267 *
01268             DO 850 L = KB - K, 1, -1
01269                NRT = ( J2+KA+L-1 ) / KA1
01270                J1T = J2 - ( NRT-1 )*KA1
01271                IF( NRT.GT.0 )
01272      $            CALL ZLARTV( NRT, AB( KA1-L+1, J1T+L-1 ), INCA,
01273      $                         AB( KA1-L, J1T+L-1 ), INCA,
01274      $                         RWORK( M-KB+J1T+KA ),
01275      $                         WORK( M-KB+J1T+KA ), KA1 )
01276   850       CONTINUE
01277             NR = ( J2+KA-1 ) / KA1
01278             J1 = J2 - ( NR-1 )*KA1
01279             DO 860 J = J1, J2, KA1
01280                WORK( M-KB+J ) = WORK( M-KB+J+KA )
01281                RWORK( M-KB+J ) = RWORK( M-KB+J+KA )
01282   860       CONTINUE
01283             DO 870 J = J1, J2, KA1
01284 *
01285 *              create nonzero element a(j+ka,j-1) outside the band
01286 *              and store it in WORK(m-kb+j)
01287 *
01288                WORK( M-KB+J ) = WORK( M-KB+J )*AB( KA1, J-1 )
01289                AB( KA1, J-1 ) = RWORK( M-KB+J )*AB( KA1, J-1 )
01290   870       CONTINUE
01291             IF( UPDATE ) THEN
01292                IF( I+K.GT.KA1 .AND. K.LE.KBT )
01293      $            WORK( M-KB+I+K-KA ) = WORK( M-KB+I+K )
01294             END IF
01295   880    CONTINUE
01296 *
01297          DO 920 K = KB, 1, -1
01298             J2 = I + K + 1 - MAX( 1, K+I0-M )*KA1
01299             NR = ( J2+KA-1 ) / KA1
01300             J1 = J2 - ( NR-1 )*KA1
01301             IF( NR.GT.0 ) THEN
01302 *
01303 *              generate rotations in 2nd set to annihilate elements
01304 *              which have been created outside the band
01305 *
01306                CALL ZLARGV( NR, AB( KA1, J1 ), INCA, WORK( M-KB+J1 ),
01307      $                      KA1, RWORK( M-KB+J1 ), KA1 )
01308 *
01309 *              apply rotations in 2nd set from the right
01310 *
01311                DO 890 L = 1, KA - 1
01312                   CALL ZLARTV( NR, AB( L+1, J1 ), INCA, AB( L+2, J1-1 ),
01313      $                         INCA, RWORK( M-KB+J1 ), WORK( M-KB+J1 ),
01314      $                         KA1 )
01315   890          CONTINUE
01316 *
01317 *              apply rotations in 2nd set from both sides to diagonal
01318 *              blocks
01319 *
01320                CALL ZLAR2V( NR, AB( 1, J1 ), AB( 1, J1-1 ),
01321      $                      AB( 2, J1-1 ), INCA, RWORK( M-KB+J1 ),
01322      $                      WORK( M-KB+J1 ), KA1 )
01323 *
01324                CALL ZLACGV( NR, WORK( M-KB+J1 ), KA1 )
01325             END IF
01326 *
01327 *           start applying rotations in 2nd set from the left
01328 *
01329             DO 900 L = KA - 1, KB - K + 1, -1
01330                NRT = ( J2+L-1 ) / KA1
01331                J1T = J2 - ( NRT-1 )*KA1
01332                IF( NRT.GT.0 )
01333      $            CALL ZLARTV( NRT, AB( KA1-L+1, J1T-KA1+L ), INCA,
01334      $                         AB( KA1-L, J1T-KA1+L ), INCA,
01335      $                         RWORK( M-KB+J1T ), WORK( M-KB+J1T ),
01336      $                         KA1 )
01337   900       CONTINUE
01338 *
01339             IF( WANTX ) THEN
01340 *
01341 *              post-multiply X by product of rotations in 2nd set
01342 *
01343                DO 910 J = J1, J2, KA1
01344                   CALL ZROT( NX, X( 1, J ), 1, X( 1, J-1 ), 1,
01345      $                       RWORK( M-KB+J ), DCONJG( WORK( M-KB+J ) ) )
01346   910          CONTINUE
01347             END IF
01348   920    CONTINUE
01349 *
01350          DO 940 K = 1, KB - 1
01351             J2 = I + K + 1 - MAX( 1, K+I0-M+1 )*KA1
01352 *
01353 *           finish applying rotations in 1st set from the left
01354 *
01355             DO 930 L = KB - K, 1, -1
01356                NRT = ( J2+L-1 ) / KA1
01357                J1T = J2 - ( NRT-1 )*KA1
01358                IF( NRT.GT.0 )
01359      $            CALL ZLARTV( NRT, AB( KA1-L+1, J1T-KA1+L ), INCA,
01360      $                         AB( KA1-L, J1T-KA1+L ), INCA,
01361      $                         RWORK( J1T ), WORK( J1T ), KA1 )
01362   930       CONTINUE
01363   940    CONTINUE
01364 *
01365          IF( KB.GT.1 ) THEN
01366             DO 950 J = 2, I2 - KA
01367                RWORK( J ) = RWORK( J+KA )
01368                WORK( J ) = WORK( J+KA )
01369   950       CONTINUE
01370          END IF
01371 *
01372       END IF
01373 *
01374       GO TO 490
01375 *
01376 *     End of ZHBGST
01377 *
01378       END
 All Files Functions