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