Annotation of rpl/lapack/lapack/dgesvd.f, revision 1.2

1.1       bertrand    1:       SUBROUTINE DGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT,
                      2:      $                   WORK, LWORK, INFO )
                      3: *
                      4: *  -- LAPACK driver 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          JOBU, JOBVT
                     11:       INTEGER            INFO, LDA, LDU, LDVT, LWORK, M, N
                     12: *     ..
                     13: *     .. Array Arguments ..
                     14:       DOUBLE PRECISION   A( LDA, * ), S( * ), U( LDU, * ),
                     15:      $                   VT( LDVT, * ), WORK( * )
                     16: *     ..
                     17: *
                     18: *  Purpose
                     19: *  =======
                     20: *
                     21: *  DGESVD computes the singular value decomposition (SVD) of a real
                     22: *  M-by-N matrix A, optionally computing the left and/or right singular
                     23: *  vectors. The SVD is written
                     24: *
                     25: *       A = U * SIGMA * transpose(V)
                     26: *
                     27: *  where SIGMA is an M-by-N matrix which is zero except for its
                     28: *  min(m,n) diagonal elements, U is an M-by-M orthogonal matrix, and
                     29: *  V is an N-by-N orthogonal matrix.  The diagonal elements of SIGMA
                     30: *  are the singular values of A; they are real and non-negative, and
                     31: *  are returned in descending order.  The first min(m,n) columns of
                     32: *  U and V are the left and right singular vectors of A.
                     33: *
                     34: *  Note that the routine returns V**T, not V.
                     35: *
                     36: *  Arguments
                     37: *  =========
                     38: *
                     39: *  JOBU    (input) CHARACTER*1
                     40: *          Specifies options for computing all or part of the matrix U:
                     41: *          = 'A':  all M columns of U are returned in array U:
                     42: *          = 'S':  the first min(m,n) columns of U (the left singular
                     43: *                  vectors) are returned in the array U;
                     44: *          = 'O':  the first min(m,n) columns of U (the left singular
                     45: *                  vectors) are overwritten on the array A;
                     46: *          = 'N':  no columns of U (no left singular vectors) are
                     47: *                  computed.
                     48: *
                     49: *  JOBVT   (input) CHARACTER*1
                     50: *          Specifies options for computing all or part of the matrix
                     51: *          V**T:
                     52: *          = 'A':  all N rows of V**T are returned in the array VT;
                     53: *          = 'S':  the first min(m,n) rows of V**T (the right singular
                     54: *                  vectors) are returned in the array VT;
                     55: *          = 'O':  the first min(m,n) rows of V**T (the right singular
                     56: *                  vectors) are overwritten on the array A;
                     57: *          = 'N':  no rows of V**T (no right singular vectors) are
                     58: *                  computed.
                     59: *
                     60: *          JOBVT and JOBU cannot both be 'O'.
                     61: *
                     62: *  M       (input) INTEGER
                     63: *          The number of rows of the input matrix A.  M >= 0.
                     64: *
                     65: *  N       (input) INTEGER
                     66: *          The number of columns of the input matrix A.  N >= 0.
                     67: *
                     68: *  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
                     69: *          On entry, the M-by-N matrix A.
                     70: *          On exit,
                     71: *          if JOBU = 'O',  A is overwritten with the first min(m,n)
                     72: *                          columns of U (the left singular vectors,
                     73: *                          stored columnwise);
                     74: *          if JOBVT = 'O', A is overwritten with the first min(m,n)
                     75: *                          rows of V**T (the right singular vectors,
                     76: *                          stored rowwise);
                     77: *          if JOBU .ne. 'O' and JOBVT .ne. 'O', the contents of A
                     78: *                          are destroyed.
                     79: *
                     80: *  LDA     (input) INTEGER
                     81: *          The leading dimension of the array A.  LDA >= max(1,M).
                     82: *
                     83: *  S       (output) DOUBLE PRECISION array, dimension (min(M,N))
                     84: *          The singular values of A, sorted so that S(i) >= S(i+1).
                     85: *
                     86: *  U       (output) DOUBLE PRECISION array, dimension (LDU,UCOL)
                     87: *          (LDU,M) if JOBU = 'A' or (LDU,min(M,N)) if JOBU = 'S'.
                     88: *          If JOBU = 'A', U contains the M-by-M orthogonal matrix U;
                     89: *          if JOBU = 'S', U contains the first min(m,n) columns of U
                     90: *          (the left singular vectors, stored columnwise);
                     91: *          if JOBU = 'N' or 'O', U is not referenced.
                     92: *
                     93: *  LDU     (input) INTEGER
                     94: *          The leading dimension of the array U.  LDU >= 1; if
                     95: *          JOBU = 'S' or 'A', LDU >= M.
                     96: *
                     97: *  VT      (output) DOUBLE PRECISION array, dimension (LDVT,N)
                     98: *          If JOBVT = 'A', VT contains the N-by-N orthogonal matrix
                     99: *          V**T;
                    100: *          if JOBVT = 'S', VT contains the first min(m,n) rows of
                    101: *          V**T (the right singular vectors, stored rowwise);
                    102: *          if JOBVT = 'N' or 'O', VT is not referenced.
                    103: *
                    104: *  LDVT    (input) INTEGER
                    105: *          The leading dimension of the array VT.  LDVT >= 1; if
                    106: *          JOBVT = 'A', LDVT >= N; if JOBVT = 'S', LDVT >= min(M,N).
                    107: *
                    108: *  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
                    109: *          On exit, if INFO = 0, WORK(1) returns the optimal LWORK;
                    110: *          if INFO > 0, WORK(2:MIN(M,N)) contains the unconverged
                    111: *          superdiagonal elements of an upper bidiagonal matrix B
                    112: *          whose diagonal is in S (not necessarily sorted). B
                    113: *          satisfies A = U * B * VT, so it has the same singular values
                    114: *          as A, and singular vectors related by U and VT.
                    115: *
                    116: *  LWORK   (input) INTEGER
                    117: *          The dimension of the array WORK.
                    118: *          LWORK >= MAX(1,3*MIN(M,N)+MAX(M,N),5*MIN(M,N)).
                    119: *          For good performance, LWORK should generally be larger.
                    120: *
                    121: *          If LWORK = -1, then a workspace query is assumed; the routine
                    122: *          only calculates the optimal size of the WORK array, returns
                    123: *          this value as the first entry of the WORK array, and no error
                    124: *          message related to LWORK is issued by XERBLA.
                    125: *
                    126: *  INFO    (output) INTEGER
                    127: *          = 0:  successful exit.
                    128: *          < 0:  if INFO = -i, the i-th argument had an illegal value.
                    129: *          > 0:  if DBDSQR did not converge, INFO specifies how many
                    130: *                superdiagonals of an intermediate bidiagonal form B
                    131: *                did not converge to zero. See the description of WORK
                    132: *                above for details.
                    133: *
                    134: *  =====================================================================
                    135: *
                    136: *     .. Parameters ..
                    137:       DOUBLE PRECISION   ZERO, ONE
                    138:       PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
                    139: *     ..
                    140: *     .. Local Scalars ..
                    141:       LOGICAL            LQUERY, WNTUA, WNTUAS, WNTUN, WNTUO, WNTUS,
                    142:      $                   WNTVA, WNTVAS, WNTVN, WNTVO, WNTVS
                    143:       INTEGER            BDSPAC, BLK, CHUNK, I, IE, IERR, IR, ISCL,
                    144:      $                   ITAU, ITAUP, ITAUQ, IU, IWORK, LDWRKR, LDWRKU,
                    145:      $                   MAXWRK, MINMN, MINWRK, MNTHR, NCU, NCVT, NRU,
                    146:      $                   NRVT, WRKBL
                    147:       DOUBLE PRECISION   ANRM, BIGNUM, EPS, SMLNUM
                    148: *     ..
                    149: *     .. Local Arrays ..
                    150:       DOUBLE PRECISION   DUM( 1 )
                    151: *     ..
                    152: *     .. External Subroutines ..
                    153:       EXTERNAL           DBDSQR, DGEBRD, DGELQF, DGEMM, DGEQRF, DLACPY,
                    154:      $                   DLASCL, DLASET, DORGBR, DORGLQ, DORGQR, DORMBR,
                    155:      $                   XERBLA
                    156: *     ..
                    157: *     .. External Functions ..
                    158:       LOGICAL            LSAME
                    159:       INTEGER            ILAENV
                    160:       DOUBLE PRECISION   DLAMCH, DLANGE
                    161:       EXTERNAL           LSAME, ILAENV, DLAMCH, DLANGE
                    162: *     ..
                    163: *     .. Intrinsic Functions ..
                    164:       INTRINSIC          MAX, MIN, SQRT
                    165: *     ..
                    166: *     .. Executable Statements ..
                    167: *
                    168: *     Test the input arguments
                    169: *
                    170:       INFO = 0
                    171:       MINMN = MIN( M, N )
                    172:       WNTUA = LSAME( JOBU, 'A' )
                    173:       WNTUS = LSAME( JOBU, 'S' )
                    174:       WNTUAS = WNTUA .OR. WNTUS
                    175:       WNTUO = LSAME( JOBU, 'O' )
                    176:       WNTUN = LSAME( JOBU, 'N' )
                    177:       WNTVA = LSAME( JOBVT, 'A' )
                    178:       WNTVS = LSAME( JOBVT, 'S' )
                    179:       WNTVAS = WNTVA .OR. WNTVS
                    180:       WNTVO = LSAME( JOBVT, 'O' )
                    181:       WNTVN = LSAME( JOBVT, 'N' )
                    182:       LQUERY = ( LWORK.EQ.-1 )
                    183: *
                    184:       IF( .NOT.( WNTUA .OR. WNTUS .OR. WNTUO .OR. WNTUN ) ) THEN
                    185:          INFO = -1
                    186:       ELSE IF( .NOT.( WNTVA .OR. WNTVS .OR. WNTVO .OR. WNTVN ) .OR.
                    187:      $         ( WNTVO .AND. WNTUO ) ) THEN
                    188:          INFO = -2
                    189:       ELSE IF( M.LT.0 ) THEN
                    190:          INFO = -3
                    191:       ELSE IF( N.LT.0 ) THEN
                    192:          INFO = -4
                    193:       ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
                    194:          INFO = -6
                    195:       ELSE IF( LDU.LT.1 .OR. ( WNTUAS .AND. LDU.LT.M ) ) THEN
                    196:          INFO = -9
                    197:       ELSE IF( LDVT.LT.1 .OR. ( WNTVA .AND. LDVT.LT.N ) .OR.
                    198:      $         ( WNTVS .AND. LDVT.LT.MINMN ) ) THEN
                    199:          INFO = -11
                    200:       END IF
                    201: *
                    202: *     Compute workspace
                    203: *      (Note: Comments in the code beginning "Workspace:" describe the
                    204: *       minimal amount of workspace needed at that point in the code,
                    205: *       as well as the preferred amount for good performance.
                    206: *       NB refers to the optimal block size for the immediately
                    207: *       following subroutine, as returned by ILAENV.)
                    208: *
                    209:       IF( INFO.EQ.0 ) THEN
                    210:          MINWRK = 1
                    211:          MAXWRK = 1
                    212:          IF( M.GE.N .AND. MINMN.GT.0 ) THEN
                    213: *
                    214: *           Compute space needed for DBDSQR
                    215: *
                    216:             MNTHR = ILAENV( 6, 'DGESVD', JOBU // JOBVT, M, N, 0, 0 )
                    217:             BDSPAC = 5*N
                    218:             IF( M.GE.MNTHR ) THEN
                    219:                IF( WNTUN ) THEN
                    220: *
                    221: *                 Path 1 (M much larger than N, JOBU='N')
                    222: *
                    223:                   MAXWRK = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1,
                    224:      $                     -1 )
                    225:                   MAXWRK = MAX( MAXWRK, 3*N+2*N*
                    226:      $                     ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
                    227:                   IF( WNTVO .OR. WNTVAS )
                    228:      $               MAXWRK = MAX( MAXWRK, 3*N+( N-1 )*
                    229:      $                        ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
                    230:                   MAXWRK = MAX( MAXWRK, BDSPAC )
                    231:                   MINWRK = MAX( 4*N, BDSPAC )
                    232:                ELSE IF( WNTUO .AND. WNTVN ) THEN
                    233: *
                    234: *                 Path 2 (M much larger than N, JOBU='O', JOBVT='N')
                    235: *
                    236:                   WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
                    237:                   WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
                    238:      $                    N, N, -1 ) )
                    239:                   WRKBL = MAX( WRKBL, 3*N+2*N*
                    240:      $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
                    241:                   WRKBL = MAX( WRKBL, 3*N+N*
                    242:      $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
                    243:                   WRKBL = MAX( WRKBL, BDSPAC )
                    244:                   MAXWRK = MAX( N*N+WRKBL, N*N+M*N+N )
                    245:                   MINWRK = MAX( 3*N+M, BDSPAC )
                    246:                ELSE IF( WNTUO .AND. WNTVAS ) THEN
                    247: *
                    248: *                 Path 3 (M much larger than N, JOBU='O', JOBVT='S' or
                    249: *                 'A')
                    250: *
                    251:                   WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
                    252:                   WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
                    253:      $                    N, N, -1 ) )
                    254:                   WRKBL = MAX( WRKBL, 3*N+2*N*
                    255:      $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
                    256:                   WRKBL = MAX( WRKBL, 3*N+N*
                    257:      $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
                    258:                   WRKBL = MAX( WRKBL, 3*N+( N-1 )*
                    259:      $                    ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
                    260:                   WRKBL = MAX( WRKBL, BDSPAC )
                    261:                   MAXWRK = MAX( N*N+WRKBL, N*N+M*N+N )
                    262:                   MINWRK = MAX( 3*N+M, BDSPAC )
                    263:                ELSE IF( WNTUS .AND. WNTVN ) THEN
                    264: *
                    265: *                 Path 4 (M much larger than N, JOBU='S', JOBVT='N')
                    266: *
                    267:                   WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
                    268:                   WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
                    269:      $                    N, N, -1 ) )
                    270:                   WRKBL = MAX( WRKBL, 3*N+2*N*
                    271:      $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
                    272:                   WRKBL = MAX( WRKBL, 3*N+N*
                    273:      $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
                    274:                   WRKBL = MAX( WRKBL, BDSPAC )
                    275:                   MAXWRK = N*N + WRKBL
                    276:                   MINWRK = MAX( 3*N+M, BDSPAC )
                    277:                ELSE IF( WNTUS .AND. WNTVO ) THEN
                    278: *
                    279: *                 Path 5 (M much larger than N, JOBU='S', JOBVT='O')
                    280: *
                    281:                   WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
                    282:                   WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
                    283:      $                    N, N, -1 ) )
                    284:                   WRKBL = MAX( WRKBL, 3*N+2*N*
                    285:      $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
                    286:                   WRKBL = MAX( WRKBL, 3*N+N*
                    287:      $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
                    288:                   WRKBL = MAX( WRKBL, 3*N+( N-1 )*
                    289:      $                    ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
                    290:                   WRKBL = MAX( WRKBL, BDSPAC )
                    291:                   MAXWRK = 2*N*N + WRKBL
                    292:                   MINWRK = MAX( 3*N+M, BDSPAC )
                    293:                ELSE IF( WNTUS .AND. WNTVAS ) THEN
                    294: *
                    295: *                 Path 6 (M much larger than N, JOBU='S', JOBVT='S' or
                    296: *                 'A')
                    297: *
                    298:                   WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
                    299:                   WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
                    300:      $                    N, N, -1 ) )
                    301:                   WRKBL = MAX( WRKBL, 3*N+2*N*
                    302:      $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
                    303:                   WRKBL = MAX( WRKBL, 3*N+N*
                    304:      $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
                    305:                   WRKBL = MAX( WRKBL, 3*N+( N-1 )*
                    306:      $                    ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
                    307:                   WRKBL = MAX( WRKBL, BDSPAC )
                    308:                   MAXWRK = N*N + WRKBL
                    309:                   MINWRK = MAX( 3*N+M, BDSPAC )
                    310:                ELSE IF( WNTUA .AND. WNTVN ) THEN
                    311: *
                    312: *                 Path 7 (M much larger than N, JOBU='A', JOBVT='N')
                    313: *
                    314:                   WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
                    315:                   WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'DORGQR', ' ', M,
                    316:      $                    M, N, -1 ) )
                    317:                   WRKBL = MAX( WRKBL, 3*N+2*N*
                    318:      $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
                    319:                   WRKBL = MAX( WRKBL, 3*N+N*
                    320:      $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
                    321:                   WRKBL = MAX( WRKBL, BDSPAC )
                    322:                   MAXWRK = N*N + WRKBL
                    323:                   MINWRK = MAX( 3*N+M, BDSPAC )
                    324:                ELSE IF( WNTUA .AND. WNTVO ) THEN
                    325: *
                    326: *                 Path 8 (M much larger than N, JOBU='A', JOBVT='O')
                    327: *
                    328:                   WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
                    329:                   WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'DORGQR', ' ', M,
                    330:      $                    M, N, -1 ) )
                    331:                   WRKBL = MAX( WRKBL, 3*N+2*N*
                    332:      $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
                    333:                   WRKBL = MAX( WRKBL, 3*N+N*
                    334:      $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
                    335:                   WRKBL = MAX( WRKBL, 3*N+( N-1 )*
                    336:      $                    ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
                    337:                   WRKBL = MAX( WRKBL, BDSPAC )
                    338:                   MAXWRK = 2*N*N + WRKBL
                    339:                   MINWRK = MAX( 3*N+M, BDSPAC )
                    340:                ELSE IF( WNTUA .AND. WNTVAS ) THEN
                    341: *
                    342: *                 Path 9 (M much larger than N, JOBU='A', JOBVT='S' or
                    343: *                 'A')
                    344: *
                    345:                   WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
                    346:                   WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'DORGQR', ' ', M,
                    347:      $                    M, N, -1 ) )
                    348:                   WRKBL = MAX( WRKBL, 3*N+2*N*
                    349:      $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
                    350:                   WRKBL = MAX( WRKBL, 3*N+N*
                    351:      $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
                    352:                   WRKBL = MAX( WRKBL, 3*N+( N-1 )*
                    353:      $                    ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
                    354:                   WRKBL = MAX( WRKBL, BDSPAC )
                    355:                   MAXWRK = N*N + WRKBL
                    356:                   MINWRK = MAX( 3*N+M, BDSPAC )
                    357:                END IF
                    358:             ELSE
                    359: *
                    360: *              Path 10 (M at least N, but not much larger)
                    361: *
                    362:                MAXWRK = 3*N + ( M+N )*ILAENV( 1, 'DGEBRD', ' ', M, N,
                    363:      $                  -1, -1 )
                    364:                IF( WNTUS .OR. WNTUO )
                    365:      $            MAXWRK = MAX( MAXWRK, 3*N+N*
                    366:      $                     ILAENV( 1, 'DORGBR', 'Q', M, N, N, -1 ) )
                    367:                IF( WNTUA )
                    368:      $            MAXWRK = MAX( MAXWRK, 3*N+M*
                    369:      $                     ILAENV( 1, 'DORGBR', 'Q', M, M, N, -1 ) )
                    370:                IF( .NOT.WNTVN )
                    371:      $            MAXWRK = MAX( MAXWRK, 3*N+( N-1 )*
                    372:      $                     ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
                    373:                MAXWRK = MAX( MAXWRK, BDSPAC )
                    374:                MINWRK = MAX( 3*N+M, BDSPAC )
                    375:             END IF
                    376:          ELSE IF( MINMN.GT.0 ) THEN
                    377: *
                    378: *           Compute space needed for DBDSQR
                    379: *
                    380:             MNTHR = ILAENV( 6, 'DGESVD', JOBU // JOBVT, M, N, 0, 0 )
                    381:             BDSPAC = 5*M
                    382:             IF( N.GE.MNTHR ) THEN
                    383:                IF( WNTVN ) THEN
                    384: *
                    385: *                 Path 1t(N much larger than M, JOBVT='N')
                    386: *
                    387:                   MAXWRK = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1,
                    388:      $                     -1 )
                    389:                   MAXWRK = MAX( MAXWRK, 3*M+2*M*
                    390:      $                     ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
                    391:                   IF( WNTUO .OR. WNTUAS )
                    392:      $               MAXWRK = MAX( MAXWRK, 3*M+M*
                    393:      $                        ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
                    394:                   MAXWRK = MAX( MAXWRK, BDSPAC )
                    395:                   MINWRK = MAX( 4*M, BDSPAC )
                    396:                ELSE IF( WNTVO .AND. WNTUN ) THEN
                    397: *
                    398: *                 Path 2t(N much larger than M, JOBU='N', JOBVT='O')
                    399: *
                    400:                   WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
                    401:                   WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
                    402:      $                    N, M, -1 ) )
                    403:                   WRKBL = MAX( WRKBL, 3*M+2*M*
                    404:      $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
                    405:                   WRKBL = MAX( WRKBL, 3*M+( M-1 )*
                    406:      $                    ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
                    407:                   WRKBL = MAX( WRKBL, BDSPAC )
                    408:                   MAXWRK = MAX( M*M+WRKBL, M*M+M*N+M )
                    409:                   MINWRK = MAX( 3*M+N, BDSPAC )
                    410:                ELSE IF( WNTVO .AND. WNTUAS ) THEN
                    411: *
                    412: *                 Path 3t(N much larger than M, JOBU='S' or 'A',
                    413: *                 JOBVT='O')
                    414: *
                    415:                   WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
                    416:                   WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
                    417:      $                    N, M, -1 ) )
                    418:                   WRKBL = MAX( WRKBL, 3*M+2*M*
                    419:      $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
                    420:                   WRKBL = MAX( WRKBL, 3*M+( M-1 )*
                    421:      $                    ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
                    422:                   WRKBL = MAX( WRKBL, 3*M+M*
                    423:      $                    ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
                    424:                   WRKBL = MAX( WRKBL, BDSPAC )
                    425:                   MAXWRK = MAX( M*M+WRKBL, M*M+M*N+M )
                    426:                   MINWRK = MAX( 3*M+N, BDSPAC )
                    427:                ELSE IF( WNTVS .AND. WNTUN ) THEN
                    428: *
                    429: *                 Path 4t(N much larger than M, JOBU='N', JOBVT='S')
                    430: *
                    431:                   WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
                    432:                   WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
                    433:      $                    N, M, -1 ) )
                    434:                   WRKBL = MAX( WRKBL, 3*M+2*M*
                    435:      $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
                    436:                   WRKBL = MAX( WRKBL, 3*M+( M-1 )*
                    437:      $                    ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
                    438:                   WRKBL = MAX( WRKBL, BDSPAC )
                    439:                   MAXWRK = M*M + WRKBL
                    440:                   MINWRK = MAX( 3*M+N, BDSPAC )
                    441:                ELSE IF( WNTVS .AND. WNTUO ) THEN
                    442: *
                    443: *                 Path 5t(N much larger than M, JOBU='O', JOBVT='S')
                    444: *
                    445:                   WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
                    446:                   WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
                    447:      $                    N, M, -1 ) )
                    448:                   WRKBL = MAX( WRKBL, 3*M+2*M*
                    449:      $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
                    450:                   WRKBL = MAX( WRKBL, 3*M+( M-1 )*
                    451:      $                    ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
                    452:                   WRKBL = MAX( WRKBL, 3*M+M*
                    453:      $                    ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
                    454:                   WRKBL = MAX( WRKBL, BDSPAC )
                    455:                   MAXWRK = 2*M*M + WRKBL
                    456:                   MINWRK = MAX( 3*M+N, BDSPAC )
                    457:                ELSE IF( WNTVS .AND. WNTUAS ) THEN
                    458: *
                    459: *                 Path 6t(N much larger than M, JOBU='S' or 'A',
                    460: *                 JOBVT='S')
                    461: *
                    462:                   WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
                    463:                   WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
                    464:      $                    N, M, -1 ) )
                    465:                   WRKBL = MAX( WRKBL, 3*M+2*M*
                    466:      $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
                    467:                   WRKBL = MAX( WRKBL, 3*M+( M-1 )*
                    468:      $                    ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
                    469:                   WRKBL = MAX( WRKBL, 3*M+M*
                    470:      $                    ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
                    471:                   WRKBL = MAX( WRKBL, BDSPAC )
                    472:                   MAXWRK = M*M + WRKBL
                    473:                   MINWRK = MAX( 3*M+N, BDSPAC )
                    474:                ELSE IF( WNTVA .AND. WNTUN ) THEN
                    475: *
                    476: *                 Path 7t(N much larger than M, JOBU='N', JOBVT='A')
                    477: *
                    478:                   WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
                    479:                   WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'DORGLQ', ' ', N,
                    480:      $                    N, M, -1 ) )
                    481:                   WRKBL = MAX( WRKBL, 3*M+2*M*
                    482:      $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
                    483:                   WRKBL = MAX( WRKBL, 3*M+( M-1 )*
                    484:      $                    ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
                    485:                   WRKBL = MAX( WRKBL, BDSPAC )
                    486:                   MAXWRK = M*M + WRKBL
                    487:                   MINWRK = MAX( 3*M+N, BDSPAC )
                    488:                ELSE IF( WNTVA .AND. WNTUO ) THEN
                    489: *
                    490: *                 Path 8t(N much larger than M, JOBU='O', JOBVT='A')
                    491: *
                    492:                   WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
                    493:                   WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'DORGLQ', ' ', N,
                    494:      $                    N, M, -1 ) )
                    495:                   WRKBL = MAX( WRKBL, 3*M+2*M*
                    496:      $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
                    497:                   WRKBL = MAX( WRKBL, 3*M+( M-1 )*
                    498:      $                    ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
                    499:                   WRKBL = MAX( WRKBL, 3*M+M*
                    500:      $                    ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
                    501:                   WRKBL = MAX( WRKBL, BDSPAC )
                    502:                   MAXWRK = 2*M*M + WRKBL
                    503:                   MINWRK = MAX( 3*M+N, BDSPAC )
                    504:                ELSE IF( WNTVA .AND. WNTUAS ) THEN
                    505: *
                    506: *                 Path 9t(N much larger than M, JOBU='S' or 'A',
                    507: *                 JOBVT='A')
                    508: *
                    509:                   WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
                    510:                   WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'DORGLQ', ' ', N,
                    511:      $                    N, M, -1 ) )
                    512:                   WRKBL = MAX( WRKBL, 3*M+2*M*
                    513:      $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
                    514:                   WRKBL = MAX( WRKBL, 3*M+( M-1 )*
                    515:      $                    ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
                    516:                   WRKBL = MAX( WRKBL, 3*M+M*
                    517:      $                    ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
                    518:                   WRKBL = MAX( WRKBL, BDSPAC )
                    519:                   MAXWRK = M*M + WRKBL
                    520:                   MINWRK = MAX( 3*M+N, BDSPAC )
                    521:                END IF
                    522:             ELSE
                    523: *
                    524: *              Path 10t(N greater than M, but not much larger)
                    525: *
                    526:                MAXWRK = 3*M + ( M+N )*ILAENV( 1, 'DGEBRD', ' ', M, N,
                    527:      $                  -1, -1 )
                    528:                IF( WNTVS .OR. WNTVO )
                    529:      $            MAXWRK = MAX( MAXWRK, 3*M+M*
                    530:      $                     ILAENV( 1, 'DORGBR', 'P', M, N, M, -1 ) )
                    531:                IF( WNTVA )
                    532:      $            MAXWRK = MAX( MAXWRK, 3*M+N*
                    533:      $                     ILAENV( 1, 'DORGBR', 'P', N, N, M, -1 ) )
                    534:                IF( .NOT.WNTUN )
                    535:      $            MAXWRK = MAX( MAXWRK, 3*M+( M-1 )*
                    536:      $                     ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
                    537:                MAXWRK = MAX( MAXWRK, BDSPAC )
                    538:                MINWRK = MAX( 3*M+N, BDSPAC )
                    539:             END IF
                    540:          END IF
                    541:          MAXWRK = MAX( MAXWRK, MINWRK )
                    542:          WORK( 1 ) = MAXWRK
                    543: *
                    544:          IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
                    545:             INFO = -13
                    546:          END IF
                    547:       END IF
                    548: *
                    549:       IF( INFO.NE.0 ) THEN
                    550:          CALL XERBLA( 'DGESVD', -INFO )
                    551:          RETURN
                    552:       ELSE IF( LQUERY ) THEN
                    553:          RETURN
                    554:       END IF
                    555: *
                    556: *     Quick return if possible
                    557: *
                    558:       IF( M.EQ.0 .OR. N.EQ.0 ) THEN
                    559:          RETURN
                    560:       END IF
                    561: *
                    562: *     Get machine constants
                    563: *
                    564:       EPS = DLAMCH( 'P' )
                    565:       SMLNUM = SQRT( DLAMCH( 'S' ) ) / EPS
                    566:       BIGNUM = ONE / SMLNUM
                    567: *
                    568: *     Scale A if max element outside range [SMLNUM,BIGNUM]
                    569: *
                    570:       ANRM = DLANGE( 'M', M, N, A, LDA, DUM )
                    571:       ISCL = 0
                    572:       IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
                    573:          ISCL = 1
                    574:          CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, IERR )
                    575:       ELSE IF( ANRM.GT.BIGNUM ) THEN
                    576:          ISCL = 1
                    577:          CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, IERR )
                    578:       END IF
                    579: *
                    580:       IF( M.GE.N ) THEN
                    581: *
                    582: *        A has at least as many rows as columns. If A has sufficiently
                    583: *        more rows than columns, first reduce using the QR
                    584: *        decomposition (if sufficient workspace available)
                    585: *
                    586:          IF( M.GE.MNTHR ) THEN
                    587: *
                    588:             IF( WNTUN ) THEN
                    589: *
                    590: *              Path 1 (M much larger than N, JOBU='N')
                    591: *              No left singular vectors to be computed
                    592: *
                    593:                ITAU = 1
                    594:                IWORK = ITAU + N
                    595: *
                    596: *              Compute A=Q*R
                    597: *              (Workspace: need 2*N, prefer N+N*NB)
                    598: *
                    599:                CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
                    600:      $                      LWORK-IWORK+1, IERR )
                    601: *
                    602: *              Zero out below R
                    603: *
                    604:                CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA )
                    605:                IE = 1
                    606:                ITAUQ = IE + N
                    607:                ITAUP = ITAUQ + N
                    608:                IWORK = ITAUP + N
                    609: *
                    610: *              Bidiagonalize R in A
                    611: *              (Workspace: need 4*N, prefer 3*N+2*N*NB)
                    612: *
                    613:                CALL DGEBRD( N, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
                    614:      $                      WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
                    615:      $                      IERR )
                    616:                NCVT = 0
                    617:                IF( WNTVO .OR. WNTVAS ) THEN
                    618: *
                    619: *                 If right singular vectors desired, generate P'.
                    620: *                 (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
                    621: *
                    622:                   CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
                    623:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                    624:                   NCVT = N
                    625:                END IF
                    626:                IWORK = IE + N
                    627: *
                    628: *              Perform bidiagonal QR iteration, computing right
                    629: *              singular vectors of A in A if desired
                    630: *              (Workspace: need BDSPAC)
                    631: *
                    632:                CALL DBDSQR( 'U', N, NCVT, 0, 0, S, WORK( IE ), A, LDA,
                    633:      $                      DUM, 1, DUM, 1, WORK( IWORK ), INFO )
                    634: *
                    635: *              If right singular vectors desired in VT, copy them there
                    636: *
                    637:                IF( WNTVAS )
                    638:      $            CALL DLACPY( 'F', N, N, A, LDA, VT, LDVT )
                    639: *
                    640:             ELSE IF( WNTUO .AND. WNTVN ) THEN
                    641: *
                    642: *              Path 2 (M much larger than N, JOBU='O', JOBVT='N')
                    643: *              N left singular vectors to be overwritten on A and
                    644: *              no right singular vectors to be computed
                    645: *
                    646:                IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN
                    647: *
                    648: *                 Sufficient workspace for a fast algorithm
                    649: *
                    650:                   IR = 1
                    651:                   IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+LDA*N ) THEN
                    652: *
                    653: *                    WORK(IU) is LDA by N, WORK(IR) is LDA by N
                    654: *
                    655:                      LDWRKU = LDA
                    656:                      LDWRKR = LDA
                    657:                   ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+N*N ) THEN
                    658: *
                    659: *                    WORK(IU) is LDA by N, WORK(IR) is N by N
                    660: *
                    661:                      LDWRKU = LDA
                    662:                      LDWRKR = N
                    663:                   ELSE
                    664: *
                    665: *                    WORK(IU) is LDWRKU by N, WORK(IR) is N by N
                    666: *
                    667:                      LDWRKU = ( LWORK-N*N-N ) / N
                    668:                      LDWRKR = N
                    669:                   END IF
                    670:                   ITAU = IR + LDWRKR*N
                    671:                   IWORK = ITAU + N
                    672: *
                    673: *                 Compute A=Q*R
                    674: *                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
                    675: *
                    676:                   CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
                    677:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                    678: *
                    679: *                 Copy R to WORK(IR) and zero out below it
                    680: *
                    681:                   CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )
                    682:                   CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, WORK( IR+1 ),
                    683:      $                         LDWRKR )
                    684: *
                    685: *                 Generate Q in A
                    686: *                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
                    687: *
                    688:                   CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
                    689:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                    690:                   IE = ITAU
                    691:                   ITAUQ = IE + N
                    692:                   ITAUP = ITAUQ + N
                    693:                   IWORK = ITAUP + N
                    694: *
                    695: *                 Bidiagonalize R in WORK(IR)
                    696: *                 (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
                    697: *
                    698:                   CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S, WORK( IE ),
                    699:      $                         WORK( ITAUQ ), WORK( ITAUP ),
                    700:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                    701: *
                    702: *                 Generate left vectors bidiagonalizing R
                    703: *                 (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
                    704: *
                    705:                   CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
                    706:      $                         WORK( ITAUQ ), WORK( IWORK ),
                    707:      $                         LWORK-IWORK+1, IERR )
                    708:                   IWORK = IE + N
                    709: *
                    710: *                 Perform bidiagonal QR iteration, computing left
                    711: *                 singular vectors of R in WORK(IR)
                    712: *                 (Workspace: need N*N+BDSPAC)
                    713: *
                    714:                   CALL DBDSQR( 'U', N, 0, N, 0, S, WORK( IE ), DUM, 1,
                    715:      $                         WORK( IR ), LDWRKR, DUM, 1,
                    716:      $                         WORK( IWORK ), INFO )
                    717:                   IU = IE + N
                    718: *
                    719: *                 Multiply Q in A by left singular vectors of R in
                    720: *                 WORK(IR), storing result in WORK(IU) and copying to A
                    721: *                 (Workspace: need N*N+2*N, prefer N*N+M*N+N)
                    722: *
                    723:                   DO 10 I = 1, M, LDWRKU
                    724:                      CHUNK = MIN( M-I+1, LDWRKU )
                    725:                      CALL DGEMM( 'N', 'N', CHUNK, N, N, ONE, A( I, 1 ),
                    726:      $                           LDA, WORK( IR ), LDWRKR, ZERO,
                    727:      $                           WORK( IU ), LDWRKU )
                    728:                      CALL DLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,
                    729:      $                            A( I, 1 ), LDA )
                    730:    10             CONTINUE
                    731: *
                    732:                ELSE
                    733: *
                    734: *                 Insufficient workspace for a fast algorithm
                    735: *
                    736:                   IE = 1
                    737:                   ITAUQ = IE + N
                    738:                   ITAUP = ITAUQ + N
                    739:                   IWORK = ITAUP + N
                    740: *
                    741: *                 Bidiagonalize A
                    742: *                 (Workspace: need 3*N+M, prefer 3*N+(M+N)*NB)
                    743: *
                    744:                   CALL DGEBRD( M, N, A, LDA, S, WORK( IE ),
                    745:      $                         WORK( ITAUQ ), WORK( ITAUP ),
                    746:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                    747: *
                    748: *                 Generate left vectors bidiagonalizing A
                    749: *                 (Workspace: need 4*N, prefer 3*N+N*NB)
                    750: *
                    751:                   CALL DORGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
                    752:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                    753:                   IWORK = IE + N
                    754: *
                    755: *                 Perform bidiagonal QR iteration, computing left
                    756: *                 singular vectors of A in A
                    757: *                 (Workspace: need BDSPAC)
                    758: *
                    759:                   CALL DBDSQR( 'U', N, 0, M, 0, S, WORK( IE ), DUM, 1,
                    760:      $                         A, LDA, DUM, 1, WORK( IWORK ), INFO )
                    761: *
                    762:                END IF
                    763: *
                    764:             ELSE IF( WNTUO .AND. WNTVAS ) THEN
                    765: *
                    766: *              Path 3 (M much larger than N, JOBU='O', JOBVT='S' or 'A')
                    767: *              N left singular vectors to be overwritten on A and
                    768: *              N right singular vectors to be computed in VT
                    769: *
                    770:                IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN
                    771: *
                    772: *                 Sufficient workspace for a fast algorithm
                    773: *
                    774:                   IR = 1
                    775:                   IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+LDA*N ) THEN
                    776: *
                    777: *                    WORK(IU) is LDA by N and WORK(IR) is LDA by N
                    778: *
                    779:                      LDWRKU = LDA
                    780:                      LDWRKR = LDA
                    781:                   ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+N*N ) THEN
                    782: *
                    783: *                    WORK(IU) is LDA by N and WORK(IR) is N by N
                    784: *
                    785:                      LDWRKU = LDA
                    786:                      LDWRKR = N
                    787:                   ELSE
                    788: *
                    789: *                    WORK(IU) is LDWRKU by N and WORK(IR) is N by N
                    790: *
                    791:                      LDWRKU = ( LWORK-N*N-N ) / N
                    792:                      LDWRKR = N
                    793:                   END IF
                    794:                   ITAU = IR + LDWRKR*N
                    795:                   IWORK = ITAU + N
                    796: *
                    797: *                 Compute A=Q*R
                    798: *                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
                    799: *
                    800:                   CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
                    801:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                    802: *
                    803: *                 Copy R to VT, zeroing out below it
                    804: *
                    805:                   CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )
                    806:                   IF( N.GT.1 )
                    807:      $               CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
                    808:      $                            VT( 2, 1 ), LDVT )
                    809: *
                    810: *                 Generate Q in A
                    811: *                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
                    812: *
                    813:                   CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
                    814:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                    815:                   IE = ITAU
                    816:                   ITAUQ = IE + N
                    817:                   ITAUP = ITAUQ + N
                    818:                   IWORK = ITAUP + N
                    819: *
                    820: *                 Bidiagonalize R in VT, copying result to WORK(IR)
                    821: *                 (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
                    822: *
                    823:                   CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),
                    824:      $                         WORK( ITAUQ ), WORK( ITAUP ),
                    825:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                    826:                   CALL DLACPY( 'L', N, N, VT, LDVT, WORK( IR ), LDWRKR )
                    827: *
                    828: *                 Generate left vectors bidiagonalizing R in WORK(IR)
                    829: *                 (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
                    830: *
                    831:                   CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
                    832:      $                         WORK( ITAUQ ), WORK( IWORK ),
                    833:      $                         LWORK-IWORK+1, IERR )
                    834: *
                    835: *                 Generate right vectors bidiagonalizing R in VT
                    836: *                 (Workspace: need N*N+4*N-1, prefer N*N+3*N+(N-1)*NB)
                    837: *
                    838:                   CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
                    839:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                    840:                   IWORK = IE + N
                    841: *
                    842: *                 Perform bidiagonal QR iteration, computing left
                    843: *                 singular vectors of R in WORK(IR) and computing right
                    844: *                 singular vectors of R in VT
                    845: *                 (Workspace: need N*N+BDSPAC)
                    846: *
                    847:                   CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ), VT, LDVT,
                    848:      $                         WORK( IR ), LDWRKR, DUM, 1,
                    849:      $                         WORK( IWORK ), INFO )
                    850:                   IU = IE + N
                    851: *
                    852: *                 Multiply Q in A by left singular vectors of R in
                    853: *                 WORK(IR), storing result in WORK(IU) and copying to A
                    854: *                 (Workspace: need N*N+2*N, prefer N*N+M*N+N)
                    855: *
                    856:                   DO 20 I = 1, M, LDWRKU
                    857:                      CHUNK = MIN( M-I+1, LDWRKU )
                    858:                      CALL DGEMM( 'N', 'N', CHUNK, N, N, ONE, A( I, 1 ),
                    859:      $                           LDA, WORK( IR ), LDWRKR, ZERO,
                    860:      $                           WORK( IU ), LDWRKU )
                    861:                      CALL DLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,
                    862:      $                            A( I, 1 ), LDA )
                    863:    20             CONTINUE
                    864: *
                    865:                ELSE
                    866: *
                    867: *                 Insufficient workspace for a fast algorithm
                    868: *
                    869:                   ITAU = 1
                    870:                   IWORK = ITAU + N
                    871: *
                    872: *                 Compute A=Q*R
                    873: *                 (Workspace: need 2*N, prefer N+N*NB)
                    874: *
                    875:                   CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
                    876:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                    877: *
                    878: *                 Copy R to VT, zeroing out below it
                    879: *
                    880:                   CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )
                    881:                   IF( N.GT.1 )
                    882:      $               CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
                    883:      $                            VT( 2, 1 ), LDVT )
                    884: *
                    885: *                 Generate Q in A
                    886: *                 (Workspace: need 2*N, prefer N+N*NB)
                    887: *
                    888:                   CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
                    889:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                    890:                   IE = ITAU
                    891:                   ITAUQ = IE + N
                    892:                   ITAUP = ITAUQ + N
                    893:                   IWORK = ITAUP + N
                    894: *
                    895: *                 Bidiagonalize R in VT
                    896: *                 (Workspace: need 4*N, prefer 3*N+2*N*NB)
                    897: *
                    898:                   CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),
                    899:      $                         WORK( ITAUQ ), WORK( ITAUP ),
                    900:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                    901: *
                    902: *                 Multiply Q in A by left vectors bidiagonalizing R
                    903: *                 (Workspace: need 3*N+M, prefer 3*N+M*NB)
                    904: *
                    905:                   CALL DORMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
                    906:      $                         WORK( ITAUQ ), A, LDA, WORK( IWORK ),
                    907:      $                         LWORK-IWORK+1, IERR )
                    908: *
                    909: *                 Generate right vectors bidiagonalizing R in VT
                    910: *                 (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
                    911: *
                    912:                   CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
                    913:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                    914:                   IWORK = IE + N
                    915: *
                    916: *                 Perform bidiagonal QR iteration, computing left
                    917: *                 singular vectors of A in A and computing right
                    918: *                 singular vectors of A in VT
                    919: *                 (Workspace: need BDSPAC)
                    920: *
                    921:                   CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), VT, LDVT,
                    922:      $                         A, LDA, DUM, 1, WORK( IWORK ), INFO )
                    923: *
                    924:                END IF
                    925: *
                    926:             ELSE IF( WNTUS ) THEN
                    927: *
                    928:                IF( WNTVN ) THEN
                    929: *
                    930: *                 Path 4 (M much larger than N, JOBU='S', JOBVT='N')
                    931: *                 N left singular vectors to be computed in U and
                    932: *                 no right singular vectors to be computed
                    933: *
                    934:                   IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN
                    935: *
                    936: *                    Sufficient workspace for a fast algorithm
                    937: *
                    938:                      IR = 1
                    939:                      IF( LWORK.GE.WRKBL+LDA*N ) THEN
                    940: *
                    941: *                       WORK(IR) is LDA by N
                    942: *
                    943:                         LDWRKR = LDA
                    944:                      ELSE
                    945: *
                    946: *                       WORK(IR) is N by N
                    947: *
                    948:                         LDWRKR = N
                    949:                      END IF
                    950:                      ITAU = IR + LDWRKR*N
                    951:                      IWORK = ITAU + N
                    952: *
                    953: *                    Compute A=Q*R
                    954: *                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
                    955: *
                    956:                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
                    957:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                    958: *
                    959: *                    Copy R to WORK(IR), zeroing out below it
                    960: *
                    961:                      CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ),
                    962:      $                            LDWRKR )
                    963:                      CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
                    964:      $                            WORK( IR+1 ), LDWRKR )
                    965: *
                    966: *                    Generate Q in A
                    967: *                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
                    968: *
                    969:                      CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
                    970:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                    971:                      IE = ITAU
                    972:                      ITAUQ = IE + N
                    973:                      ITAUP = ITAUQ + N
                    974:                      IWORK = ITAUP + N
                    975: *
                    976: *                    Bidiagonalize R in WORK(IR)
                    977: *                    (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
                    978: *
                    979:                      CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S,
                    980:      $                            WORK( IE ), WORK( ITAUQ ),
                    981:      $                            WORK( ITAUP ), WORK( IWORK ),
                    982:      $                            LWORK-IWORK+1, IERR )
                    983: *
                    984: *                    Generate left vectors bidiagonalizing R in WORK(IR)
                    985: *                    (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
                    986: *
                    987:                      CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
                    988:      $                            WORK( ITAUQ ), WORK( IWORK ),
                    989:      $                            LWORK-IWORK+1, IERR )
                    990:                      IWORK = IE + N
                    991: *
                    992: *                    Perform bidiagonal QR iteration, computing left
                    993: *                    singular vectors of R in WORK(IR)
                    994: *                    (Workspace: need N*N+BDSPAC)
                    995: *
                    996:                      CALL DBDSQR( 'U', N, 0, N, 0, S, WORK( IE ), DUM,
                    997:      $                            1, WORK( IR ), LDWRKR, DUM, 1,
                    998:      $                            WORK( IWORK ), INFO )
                    999: *
                   1000: *                    Multiply Q in A by left singular vectors of R in
                   1001: *                    WORK(IR), storing result in U
                   1002: *                    (Workspace: need N*N)
                   1003: *
                   1004:                      CALL DGEMM( 'N', 'N', M, N, N, ONE, A, LDA,
                   1005:      $                           WORK( IR ), LDWRKR, ZERO, U, LDU )
                   1006: *
                   1007:                   ELSE
                   1008: *
                   1009: *                    Insufficient workspace for a fast algorithm
                   1010: *
                   1011:                      ITAU = 1
                   1012:                      IWORK = ITAU + N
                   1013: *
                   1014: *                    Compute A=Q*R, copying result to U
                   1015: *                    (Workspace: need 2*N, prefer N+N*NB)
                   1016: *
                   1017:                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
                   1018:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1019:                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
                   1020: *
                   1021: *                    Generate Q in U
                   1022: *                    (Workspace: need 2*N, prefer N+N*NB)
                   1023: *
                   1024:                      CALL DORGQR( M, N, N, U, LDU, WORK( ITAU ),
                   1025:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1026:                      IE = ITAU
                   1027:                      ITAUQ = IE + N
                   1028:                      ITAUP = ITAUQ + N
                   1029:                      IWORK = ITAUP + N
                   1030: *
                   1031: *                    Zero out below R in A
                   1032: *
                   1033:                      CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
                   1034:      $                            LDA )
                   1035: *
                   1036: *                    Bidiagonalize R in A
                   1037: *                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
                   1038: *
                   1039:                      CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),
                   1040:      $                            WORK( ITAUQ ), WORK( ITAUP ),
                   1041:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1042: *
                   1043: *                    Multiply Q in U by left vectors bidiagonalizing R
                   1044: *                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
                   1045: *
                   1046:                      CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
                   1047:      $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
                   1048:      $                            LWORK-IWORK+1, IERR )
                   1049:                      IWORK = IE + N
                   1050: *
                   1051: *                    Perform bidiagonal QR iteration, computing left
                   1052: *                    singular vectors of A in U
                   1053: *                    (Workspace: need BDSPAC)
                   1054: *
                   1055:                      CALL DBDSQR( 'U', N, 0, M, 0, S, WORK( IE ), DUM,
                   1056:      $                            1, U, LDU, DUM, 1, WORK( IWORK ),
                   1057:      $                            INFO )
                   1058: *
                   1059:                   END IF
                   1060: *
                   1061:                ELSE IF( WNTVO ) THEN
                   1062: *
                   1063: *                 Path 5 (M much larger than N, JOBU='S', JOBVT='O')
                   1064: *                 N left singular vectors to be computed in U and
                   1065: *                 N right singular vectors to be overwritten on A
                   1066: *
                   1067:                   IF( LWORK.GE.2*N*N+MAX( 4*N, BDSPAC ) ) THEN
                   1068: *
                   1069: *                    Sufficient workspace for a fast algorithm
                   1070: *
                   1071:                      IU = 1
                   1072:                      IF( LWORK.GE.WRKBL+2*LDA*N ) THEN
                   1073: *
                   1074: *                       WORK(IU) is LDA by N and WORK(IR) is LDA by N
                   1075: *
                   1076:                         LDWRKU = LDA
                   1077:                         IR = IU + LDWRKU*N
                   1078:                         LDWRKR = LDA
                   1079:                      ELSE IF( LWORK.GE.WRKBL+( LDA+N )*N ) THEN
                   1080: *
                   1081: *                       WORK(IU) is LDA by N and WORK(IR) is N by N
                   1082: *
                   1083:                         LDWRKU = LDA
                   1084:                         IR = IU + LDWRKU*N
                   1085:                         LDWRKR = N
                   1086:                      ELSE
                   1087: *
                   1088: *                       WORK(IU) is N by N and WORK(IR) is N by N
                   1089: *
                   1090:                         LDWRKU = N
                   1091:                         IR = IU + LDWRKU*N
                   1092:                         LDWRKR = N
                   1093:                      END IF
                   1094:                      ITAU = IR + LDWRKR*N
                   1095:                      IWORK = ITAU + N
                   1096: *
                   1097: *                    Compute A=Q*R
                   1098: *                    (Workspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)
                   1099: *
                   1100:                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
                   1101:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1102: *
                   1103: *                    Copy R to WORK(IU), zeroing out below it
                   1104: *
                   1105:                      CALL DLACPY( 'U', N, N, A, LDA, WORK( IU ),
                   1106:      $                            LDWRKU )
                   1107:                      CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
                   1108:      $                            WORK( IU+1 ), LDWRKU )
                   1109: *
                   1110: *                    Generate Q in A
                   1111: *                    (Workspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)
                   1112: *
                   1113:                      CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
                   1114:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1115:                      IE = ITAU
                   1116:                      ITAUQ = IE + N
                   1117:                      ITAUP = ITAUQ + N
                   1118:                      IWORK = ITAUP + N
                   1119: *
                   1120: *                    Bidiagonalize R in WORK(IU), copying result to
                   1121: *                    WORK(IR)
                   1122: *                    (Workspace: need 2*N*N+4*N,
                   1123: *                                prefer 2*N*N+3*N+2*N*NB)
                   1124: *
                   1125:                      CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,
                   1126:      $                            WORK( IE ), WORK( ITAUQ ),
                   1127:      $                            WORK( ITAUP ), WORK( IWORK ),
                   1128:      $                            LWORK-IWORK+1, IERR )
                   1129:                      CALL DLACPY( 'U', N, N, WORK( IU ), LDWRKU,
                   1130:      $                            WORK( IR ), LDWRKR )
                   1131: *
                   1132: *                    Generate left bidiagonalizing vectors in WORK(IU)
                   1133: *                    (Workspace: need 2*N*N+4*N, prefer 2*N*N+3*N+N*NB)
                   1134: *
                   1135:                      CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
                   1136:      $                            WORK( ITAUQ ), WORK( IWORK ),
                   1137:      $                            LWORK-IWORK+1, IERR )
                   1138: *
                   1139: *                    Generate right bidiagonalizing vectors in WORK(IR)
                   1140: *                    (Workspace: need 2*N*N+4*N-1,
                   1141: *                                prefer 2*N*N+3*N+(N-1)*NB)
                   1142: *
                   1143:                      CALL DORGBR( 'P', N, N, N, WORK( IR ), LDWRKR,
                   1144:      $                            WORK( ITAUP ), WORK( IWORK ),
                   1145:      $                            LWORK-IWORK+1, IERR )
                   1146:                      IWORK = IE + N
                   1147: *
                   1148: *                    Perform bidiagonal QR iteration, computing left
                   1149: *                    singular vectors of R in WORK(IU) and computing
                   1150: *                    right singular vectors of R in WORK(IR)
                   1151: *                    (Workspace: need 2*N*N+BDSPAC)
                   1152: *
                   1153:                      CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ),
                   1154:      $                            WORK( IR ), LDWRKR, WORK( IU ),
                   1155:      $                            LDWRKU, DUM, 1, WORK( IWORK ), INFO )
                   1156: *
                   1157: *                    Multiply Q in A by left singular vectors of R in
                   1158: *                    WORK(IU), storing result in U
                   1159: *                    (Workspace: need N*N)
                   1160: *
                   1161:                      CALL DGEMM( 'N', 'N', M, N, N, ONE, A, LDA,
                   1162:      $                           WORK( IU ), LDWRKU, ZERO, U, LDU )
                   1163: *
                   1164: *                    Copy right singular vectors of R to A
                   1165: *                    (Workspace: need N*N)
                   1166: *
                   1167:                      CALL DLACPY( 'F', N, N, WORK( IR ), LDWRKR, A,
                   1168:      $                            LDA )
                   1169: *
                   1170:                   ELSE
                   1171: *
                   1172: *                    Insufficient workspace for a fast algorithm
                   1173: *
                   1174:                      ITAU = 1
                   1175:                      IWORK = ITAU + N
                   1176: *
                   1177: *                    Compute A=Q*R, copying result to U
                   1178: *                    (Workspace: need 2*N, prefer N+N*NB)
                   1179: *
                   1180:                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
                   1181:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1182:                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
                   1183: *
                   1184: *                    Generate Q in U
                   1185: *                    (Workspace: need 2*N, prefer N+N*NB)
                   1186: *
                   1187:                      CALL DORGQR( M, N, N, U, LDU, WORK( ITAU ),
                   1188:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1189:                      IE = ITAU
                   1190:                      ITAUQ = IE + N
                   1191:                      ITAUP = ITAUQ + N
                   1192:                      IWORK = ITAUP + N
                   1193: *
                   1194: *                    Zero out below R in A
                   1195: *
                   1196:                      CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
                   1197:      $                            LDA )
                   1198: *
                   1199: *                    Bidiagonalize R in A
                   1200: *                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
                   1201: *
                   1202:                      CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),
                   1203:      $                            WORK( ITAUQ ), WORK( ITAUP ),
                   1204:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1205: *
                   1206: *                    Multiply Q in U by left vectors bidiagonalizing R
                   1207: *                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
                   1208: *
                   1209:                      CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
                   1210:      $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
                   1211:      $                            LWORK-IWORK+1, IERR )
                   1212: *
                   1213: *                    Generate right vectors bidiagonalizing R in A
                   1214: *                    (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
                   1215: *
                   1216:                      CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
                   1217:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1218:                      IWORK = IE + N
                   1219: *
                   1220: *                    Perform bidiagonal QR iteration, computing left
                   1221: *                    singular vectors of A in U and computing right
                   1222: *                    singular vectors of A in A
                   1223: *                    (Workspace: need BDSPAC)
                   1224: *
                   1225:                      CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), A,
                   1226:      $                            LDA, U, LDU, DUM, 1, WORK( IWORK ),
                   1227:      $                            INFO )
                   1228: *
                   1229:                   END IF
                   1230: *
                   1231:                ELSE IF( WNTVAS ) THEN
                   1232: *
                   1233: *                 Path 6 (M much larger than N, JOBU='S', JOBVT='S'
                   1234: *                         or 'A')
                   1235: *                 N left singular vectors to be computed in U and
                   1236: *                 N right singular vectors to be computed in VT
                   1237: *
                   1238:                   IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN
                   1239: *
                   1240: *                    Sufficient workspace for a fast algorithm
                   1241: *
                   1242:                      IU = 1
                   1243:                      IF( LWORK.GE.WRKBL+LDA*N ) THEN
                   1244: *
                   1245: *                       WORK(IU) is LDA by N
                   1246: *
                   1247:                         LDWRKU = LDA
                   1248:                      ELSE
                   1249: *
                   1250: *                       WORK(IU) is N by N
                   1251: *
                   1252:                         LDWRKU = N
                   1253:                      END IF
                   1254:                      ITAU = IU + LDWRKU*N
                   1255:                      IWORK = ITAU + N
                   1256: *
                   1257: *                    Compute A=Q*R
                   1258: *                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
                   1259: *
                   1260:                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
                   1261:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1262: *
                   1263: *                    Copy R to WORK(IU), zeroing out below it
                   1264: *
                   1265:                      CALL DLACPY( 'U', N, N, A, LDA, WORK( IU ),
                   1266:      $                            LDWRKU )
                   1267:                      CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
                   1268:      $                            WORK( IU+1 ), LDWRKU )
                   1269: *
                   1270: *                    Generate Q in A
                   1271: *                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
                   1272: *
                   1273:                      CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
                   1274:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1275:                      IE = ITAU
                   1276:                      ITAUQ = IE + N
                   1277:                      ITAUP = ITAUQ + N
                   1278:                      IWORK = ITAUP + N
                   1279: *
                   1280: *                    Bidiagonalize R in WORK(IU), copying result to VT
                   1281: *                    (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
                   1282: *
                   1283:                      CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,
                   1284:      $                            WORK( IE ), WORK( ITAUQ ),
                   1285:      $                            WORK( ITAUP ), WORK( IWORK ),
                   1286:      $                            LWORK-IWORK+1, IERR )
                   1287:                      CALL DLACPY( 'U', N, N, WORK( IU ), LDWRKU, VT,
                   1288:      $                            LDVT )
                   1289: *
                   1290: *                    Generate left bidiagonalizing vectors in WORK(IU)
                   1291: *                    (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
                   1292: *
                   1293:                      CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
                   1294:      $                            WORK( ITAUQ ), WORK( IWORK ),
                   1295:      $                            LWORK-IWORK+1, IERR )
                   1296: *
                   1297: *                    Generate right bidiagonalizing vectors in VT
                   1298: *                    (Workspace: need N*N+4*N-1,
                   1299: *                                prefer N*N+3*N+(N-1)*NB)
                   1300: *
                   1301:                      CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
                   1302:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1303:                      IWORK = IE + N
                   1304: *
                   1305: *                    Perform bidiagonal QR iteration, computing left
                   1306: *                    singular vectors of R in WORK(IU) and computing
                   1307: *                    right singular vectors of R in VT
                   1308: *                    (Workspace: need N*N+BDSPAC)
                   1309: *
                   1310:                      CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ), VT,
                   1311:      $                            LDVT, WORK( IU ), LDWRKU, DUM, 1,
                   1312:      $                            WORK( IWORK ), INFO )
                   1313: *
                   1314: *                    Multiply Q in A by left singular vectors of R in
                   1315: *                    WORK(IU), storing result in U
                   1316: *                    (Workspace: need N*N)
                   1317: *
                   1318:                      CALL DGEMM( 'N', 'N', M, N, N, ONE, A, LDA,
                   1319:      $                           WORK( IU ), LDWRKU, ZERO, U, LDU )
                   1320: *
                   1321:                   ELSE
                   1322: *
                   1323: *                    Insufficient workspace for a fast algorithm
                   1324: *
                   1325:                      ITAU = 1
                   1326:                      IWORK = ITAU + N
                   1327: *
                   1328: *                    Compute A=Q*R, copying result to U
                   1329: *                    (Workspace: need 2*N, prefer N+N*NB)
                   1330: *
                   1331:                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
                   1332:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1333:                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
                   1334: *
                   1335: *                    Generate Q in U
                   1336: *                    (Workspace: need 2*N, prefer N+N*NB)
                   1337: *
                   1338:                      CALL DORGQR( M, N, N, U, LDU, WORK( ITAU ),
                   1339:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1340: *
                   1341: *                    Copy R to VT, zeroing out below it
                   1342: *
                   1343:                      CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )
                   1344:                      IF( N.GT.1 )
                   1345:      $                  CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
                   1346:      $                               VT( 2, 1 ), LDVT )
                   1347:                      IE = ITAU
                   1348:                      ITAUQ = IE + N
                   1349:                      ITAUP = ITAUQ + N
                   1350:                      IWORK = ITAUP + N
                   1351: *
                   1352: *                    Bidiagonalize R in VT
                   1353: *                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
                   1354: *
                   1355:                      CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),
                   1356:      $                            WORK( ITAUQ ), WORK( ITAUP ),
                   1357:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1358: *
                   1359: *                    Multiply Q in U by left bidiagonalizing vectors
                   1360: *                    in VT
                   1361: *                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
                   1362: *
                   1363:                      CALL DORMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
                   1364:      $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
                   1365:      $                            LWORK-IWORK+1, IERR )
                   1366: *
                   1367: *                    Generate right bidiagonalizing vectors in VT
                   1368: *                    (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
                   1369: *
                   1370:                      CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
                   1371:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1372:                      IWORK = IE + N
                   1373: *
                   1374: *                    Perform bidiagonal QR iteration, computing left
                   1375: *                    singular vectors of A in U and computing right
                   1376: *                    singular vectors of A in VT
                   1377: *                    (Workspace: need BDSPAC)
                   1378: *
                   1379:                      CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), VT,
                   1380:      $                            LDVT, U, LDU, DUM, 1, WORK( IWORK ),
                   1381:      $                            INFO )
                   1382: *
                   1383:                   END IF
                   1384: *
                   1385:                END IF
                   1386: *
                   1387:             ELSE IF( WNTUA ) THEN
                   1388: *
                   1389:                IF( WNTVN ) THEN
                   1390: *
                   1391: *                 Path 7 (M much larger than N, JOBU='A', JOBVT='N')
                   1392: *                 M left singular vectors to be computed in U and
                   1393: *                 no right singular vectors to be computed
                   1394: *
                   1395:                   IF( LWORK.GE.N*N+MAX( N+M, 4*N, BDSPAC ) ) THEN
                   1396: *
                   1397: *                    Sufficient workspace for a fast algorithm
                   1398: *
                   1399:                      IR = 1
                   1400:                      IF( LWORK.GE.WRKBL+LDA*N ) THEN
                   1401: *
                   1402: *                       WORK(IR) is LDA by N
                   1403: *
                   1404:                         LDWRKR = LDA
                   1405:                      ELSE
                   1406: *
                   1407: *                       WORK(IR) is N by N
                   1408: *
                   1409:                         LDWRKR = N
                   1410:                      END IF
                   1411:                      ITAU = IR + LDWRKR*N
                   1412:                      IWORK = ITAU + N
                   1413: *
                   1414: *                    Compute A=Q*R, copying result to U
                   1415: *                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
                   1416: *
                   1417:                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
                   1418:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1419:                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
                   1420: *
                   1421: *                    Copy R to WORK(IR), zeroing out below it
                   1422: *
                   1423:                      CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ),
                   1424:      $                            LDWRKR )
                   1425:                      CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
                   1426:      $                            WORK( IR+1 ), LDWRKR )
                   1427: *
                   1428: *                    Generate Q in U
                   1429: *                    (Workspace: need N*N+N+M, prefer N*N+N+M*NB)
                   1430: *
                   1431:                      CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
                   1432:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1433:                      IE = ITAU
                   1434:                      ITAUQ = IE + N
                   1435:                      ITAUP = ITAUQ + N
                   1436:                      IWORK = ITAUP + N
                   1437: *
                   1438: *                    Bidiagonalize R in WORK(IR)
                   1439: *                    (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
                   1440: *
                   1441:                      CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S,
                   1442:      $                            WORK( IE ), WORK( ITAUQ ),
                   1443:      $                            WORK( ITAUP ), WORK( IWORK ),
                   1444:      $                            LWORK-IWORK+1, IERR )
                   1445: *
                   1446: *                    Generate left bidiagonalizing vectors in WORK(IR)
                   1447: *                    (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
                   1448: *
                   1449:                      CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
                   1450:      $                            WORK( ITAUQ ), WORK( IWORK ),
                   1451:      $                            LWORK-IWORK+1, IERR )
                   1452:                      IWORK = IE + N
                   1453: *
                   1454: *                    Perform bidiagonal QR iteration, computing left
                   1455: *                    singular vectors of R in WORK(IR)
                   1456: *                    (Workspace: need N*N+BDSPAC)
                   1457: *
                   1458:                      CALL DBDSQR( 'U', N, 0, N, 0, S, WORK( IE ), DUM,
                   1459:      $                            1, WORK( IR ), LDWRKR, DUM, 1,
                   1460:      $                            WORK( IWORK ), INFO )
                   1461: *
                   1462: *                    Multiply Q in U by left singular vectors of R in
                   1463: *                    WORK(IR), storing result in A
                   1464: *                    (Workspace: need N*N)
                   1465: *
                   1466:                      CALL DGEMM( 'N', 'N', M, N, N, ONE, U, LDU,
                   1467:      $                           WORK( IR ), LDWRKR, ZERO, A, LDA )
                   1468: *
                   1469: *                    Copy left singular vectors of A from A to U
                   1470: *
                   1471:                      CALL DLACPY( 'F', M, N, A, LDA, U, LDU )
                   1472: *
                   1473:                   ELSE
                   1474: *
                   1475: *                    Insufficient workspace for a fast algorithm
                   1476: *
                   1477:                      ITAU = 1
                   1478:                      IWORK = ITAU + N
                   1479: *
                   1480: *                    Compute A=Q*R, copying result to U
                   1481: *                    (Workspace: need 2*N, prefer N+N*NB)
                   1482: *
                   1483:                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
                   1484:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1485:                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
                   1486: *
                   1487: *                    Generate Q in U
                   1488: *                    (Workspace: need N+M, prefer N+M*NB)
                   1489: *
                   1490:                      CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
                   1491:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1492:                      IE = ITAU
                   1493:                      ITAUQ = IE + N
                   1494:                      ITAUP = ITAUQ + N
                   1495:                      IWORK = ITAUP + N
                   1496: *
                   1497: *                    Zero out below R in A
                   1498: *
                   1499:                      CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
                   1500:      $                            LDA )
                   1501: *
                   1502: *                    Bidiagonalize R in A
                   1503: *                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
                   1504: *
                   1505:                      CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),
                   1506:      $                            WORK( ITAUQ ), WORK( ITAUP ),
                   1507:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1508: *
                   1509: *                    Multiply Q in U by left bidiagonalizing vectors
                   1510: *                    in A
                   1511: *                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
                   1512: *
                   1513:                      CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
                   1514:      $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
                   1515:      $                            LWORK-IWORK+1, IERR )
                   1516:                      IWORK = IE + N
                   1517: *
                   1518: *                    Perform bidiagonal QR iteration, computing left
                   1519: *                    singular vectors of A in U
                   1520: *                    (Workspace: need BDSPAC)
                   1521: *
                   1522:                      CALL DBDSQR( 'U', N, 0, M, 0, S, WORK( IE ), DUM,
                   1523:      $                            1, U, LDU, DUM, 1, WORK( IWORK ),
                   1524:      $                            INFO )
                   1525: *
                   1526:                   END IF
                   1527: *
                   1528:                ELSE IF( WNTVO ) THEN
                   1529: *
                   1530: *                 Path 8 (M much larger than N, JOBU='A', JOBVT='O')
                   1531: *                 M left singular vectors to be computed in U and
                   1532: *                 N right singular vectors to be overwritten on A
                   1533: *
                   1534:                   IF( LWORK.GE.2*N*N+MAX( N+M, 4*N, BDSPAC ) ) THEN
                   1535: *
                   1536: *                    Sufficient workspace for a fast algorithm
                   1537: *
                   1538:                      IU = 1
                   1539:                      IF( LWORK.GE.WRKBL+2*LDA*N ) THEN
                   1540: *
                   1541: *                       WORK(IU) is LDA by N and WORK(IR) is LDA by N
                   1542: *
                   1543:                         LDWRKU = LDA
                   1544:                         IR = IU + LDWRKU*N
                   1545:                         LDWRKR = LDA
                   1546:                      ELSE IF( LWORK.GE.WRKBL+( LDA+N )*N ) THEN
                   1547: *
                   1548: *                       WORK(IU) is LDA by N and WORK(IR) is N by N
                   1549: *
                   1550:                         LDWRKU = LDA
                   1551:                         IR = IU + LDWRKU*N
                   1552:                         LDWRKR = N
                   1553:                      ELSE
                   1554: *
                   1555: *                       WORK(IU) is N by N and WORK(IR) is N by N
                   1556: *
                   1557:                         LDWRKU = N
                   1558:                         IR = IU + LDWRKU*N
                   1559:                         LDWRKR = N
                   1560:                      END IF
                   1561:                      ITAU = IR + LDWRKR*N
                   1562:                      IWORK = ITAU + N
                   1563: *
                   1564: *                    Compute A=Q*R, copying result to U
                   1565: *                    (Workspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)
                   1566: *
                   1567:                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
                   1568:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1569:                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
                   1570: *
                   1571: *                    Generate Q in U
                   1572: *                    (Workspace: need 2*N*N+N+M, prefer 2*N*N+N+M*NB)
                   1573: *
                   1574:                      CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
                   1575:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1576: *
                   1577: *                    Copy R to WORK(IU), zeroing out below it
                   1578: *
                   1579:                      CALL DLACPY( 'U', N, N, A, LDA, WORK( IU ),
                   1580:      $                            LDWRKU )
                   1581:                      CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
                   1582:      $                            WORK( IU+1 ), LDWRKU )
                   1583:                      IE = ITAU
                   1584:                      ITAUQ = IE + N
                   1585:                      ITAUP = ITAUQ + N
                   1586:                      IWORK = ITAUP + N
                   1587: *
                   1588: *                    Bidiagonalize R in WORK(IU), copying result to
                   1589: *                    WORK(IR)
                   1590: *                    (Workspace: need 2*N*N+4*N,
                   1591: *                                prefer 2*N*N+3*N+2*N*NB)
                   1592: *
                   1593:                      CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,
                   1594:      $                            WORK( IE ), WORK( ITAUQ ),
                   1595:      $                            WORK( ITAUP ), WORK( IWORK ),
                   1596:      $                            LWORK-IWORK+1, IERR )
                   1597:                      CALL DLACPY( 'U', N, N, WORK( IU ), LDWRKU,
                   1598:      $                            WORK( IR ), LDWRKR )
                   1599: *
                   1600: *                    Generate left bidiagonalizing vectors in WORK(IU)
                   1601: *                    (Workspace: need 2*N*N+4*N, prefer 2*N*N+3*N+N*NB)
                   1602: *
                   1603:                      CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
                   1604:      $                            WORK( ITAUQ ), WORK( IWORK ),
                   1605:      $                            LWORK-IWORK+1, IERR )
                   1606: *
                   1607: *                    Generate right bidiagonalizing vectors in WORK(IR)
                   1608: *                    (Workspace: need 2*N*N+4*N-1,
                   1609: *                                prefer 2*N*N+3*N+(N-1)*NB)
                   1610: *
                   1611:                      CALL DORGBR( 'P', N, N, N, WORK( IR ), LDWRKR,
                   1612:      $                            WORK( ITAUP ), WORK( IWORK ),
                   1613:      $                            LWORK-IWORK+1, IERR )
                   1614:                      IWORK = IE + N
                   1615: *
                   1616: *                    Perform bidiagonal QR iteration, computing left
                   1617: *                    singular vectors of R in WORK(IU) and computing
                   1618: *                    right singular vectors of R in WORK(IR)
                   1619: *                    (Workspace: need 2*N*N+BDSPAC)
                   1620: *
                   1621:                      CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ),
                   1622:      $                            WORK( IR ), LDWRKR, WORK( IU ),
                   1623:      $                            LDWRKU, DUM, 1, WORK( IWORK ), INFO )
                   1624: *
                   1625: *                    Multiply Q in U by left singular vectors of R in
                   1626: *                    WORK(IU), storing result in A
                   1627: *                    (Workspace: need N*N)
                   1628: *
                   1629:                      CALL DGEMM( 'N', 'N', M, N, N, ONE, U, LDU,
                   1630:      $                           WORK( IU ), LDWRKU, ZERO, A, LDA )
                   1631: *
                   1632: *                    Copy left singular vectors of A from A to U
                   1633: *
                   1634:                      CALL DLACPY( 'F', M, N, A, LDA, U, LDU )
                   1635: *
                   1636: *                    Copy right singular vectors of R from WORK(IR) to A
                   1637: *
                   1638:                      CALL DLACPY( 'F', N, N, WORK( IR ), LDWRKR, A,
                   1639:      $                            LDA )
                   1640: *
                   1641:                   ELSE
                   1642: *
                   1643: *                    Insufficient workspace for a fast algorithm
                   1644: *
                   1645:                      ITAU = 1
                   1646:                      IWORK = ITAU + N
                   1647: *
                   1648: *                    Compute A=Q*R, copying result to U
                   1649: *                    (Workspace: need 2*N, prefer N+N*NB)
                   1650: *
                   1651:                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
                   1652:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1653:                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
                   1654: *
                   1655: *                    Generate Q in U
                   1656: *                    (Workspace: need N+M, prefer N+M*NB)
                   1657: *
                   1658:                      CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
                   1659:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1660:                      IE = ITAU
                   1661:                      ITAUQ = IE + N
                   1662:                      ITAUP = ITAUQ + N
                   1663:                      IWORK = ITAUP + N
                   1664: *
                   1665: *                    Zero out below R in A
                   1666: *
                   1667:                      CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
                   1668:      $                            LDA )
                   1669: *
                   1670: *                    Bidiagonalize R in A
                   1671: *                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
                   1672: *
                   1673:                      CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),
                   1674:      $                            WORK( ITAUQ ), WORK( ITAUP ),
                   1675:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1676: *
                   1677: *                    Multiply Q in U by left bidiagonalizing vectors
                   1678: *                    in A
                   1679: *                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
                   1680: *
                   1681:                      CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
                   1682:      $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
                   1683:      $                            LWORK-IWORK+1, IERR )
                   1684: *
                   1685: *                    Generate right bidiagonalizing vectors in A
                   1686: *                    (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
                   1687: *
                   1688:                      CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
                   1689:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1690:                      IWORK = IE + N
                   1691: *
                   1692: *                    Perform bidiagonal QR iteration, computing left
                   1693: *                    singular vectors of A in U and computing right
                   1694: *                    singular vectors of A in A
                   1695: *                    (Workspace: need BDSPAC)
                   1696: *
                   1697:                      CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), A,
                   1698:      $                            LDA, U, LDU, DUM, 1, WORK( IWORK ),
                   1699:      $                            INFO )
                   1700: *
                   1701:                   END IF
                   1702: *
                   1703:                ELSE IF( WNTVAS ) THEN
                   1704: *
                   1705: *                 Path 9 (M much larger than N, JOBU='A', JOBVT='S'
                   1706: *                         or 'A')
                   1707: *                 M left singular vectors to be computed in U and
                   1708: *                 N right singular vectors to be computed in VT
                   1709: *
                   1710:                   IF( LWORK.GE.N*N+MAX( N+M, 4*N, BDSPAC ) ) THEN
                   1711: *
                   1712: *                    Sufficient workspace for a fast algorithm
                   1713: *
                   1714:                      IU = 1
                   1715:                      IF( LWORK.GE.WRKBL+LDA*N ) THEN
                   1716: *
                   1717: *                       WORK(IU) is LDA by N
                   1718: *
                   1719:                         LDWRKU = LDA
                   1720:                      ELSE
                   1721: *
                   1722: *                       WORK(IU) is N by N
                   1723: *
                   1724:                         LDWRKU = N
                   1725:                      END IF
                   1726:                      ITAU = IU + LDWRKU*N
                   1727:                      IWORK = ITAU + N
                   1728: *
                   1729: *                    Compute A=Q*R, copying result to U
                   1730: *                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
                   1731: *
                   1732:                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
                   1733:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1734:                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
                   1735: *
                   1736: *                    Generate Q in U
                   1737: *                    (Workspace: need N*N+N+M, prefer N*N+N+M*NB)
                   1738: *
                   1739:                      CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
                   1740:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1741: *
                   1742: *                    Copy R to WORK(IU), zeroing out below it
                   1743: *
                   1744:                      CALL DLACPY( 'U', N, N, A, LDA, WORK( IU ),
                   1745:      $                            LDWRKU )
                   1746:                      CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
                   1747:      $                            WORK( IU+1 ), LDWRKU )
                   1748:                      IE = ITAU
                   1749:                      ITAUQ = IE + N
                   1750:                      ITAUP = ITAUQ + N
                   1751:                      IWORK = ITAUP + N
                   1752: *
                   1753: *                    Bidiagonalize R in WORK(IU), copying result to VT
                   1754: *                    (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
                   1755: *
                   1756:                      CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,
                   1757:      $                            WORK( IE ), WORK( ITAUQ ),
                   1758:      $                            WORK( ITAUP ), WORK( IWORK ),
                   1759:      $                            LWORK-IWORK+1, IERR )
                   1760:                      CALL DLACPY( 'U', N, N, WORK( IU ), LDWRKU, VT,
                   1761:      $                            LDVT )
                   1762: *
                   1763: *                    Generate left bidiagonalizing vectors in WORK(IU)
                   1764: *                    (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
                   1765: *
                   1766:                      CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
                   1767:      $                            WORK( ITAUQ ), WORK( IWORK ),
                   1768:      $                            LWORK-IWORK+1, IERR )
                   1769: *
                   1770: *                    Generate right bidiagonalizing vectors in VT
                   1771: *                    (Workspace: need N*N+4*N-1,
                   1772: *                                prefer N*N+3*N+(N-1)*NB)
                   1773: *
                   1774:                      CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
                   1775:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1776:                      IWORK = IE + N
                   1777: *
                   1778: *                    Perform bidiagonal QR iteration, computing left
                   1779: *                    singular vectors of R in WORK(IU) and computing
                   1780: *                    right singular vectors of R in VT
                   1781: *                    (Workspace: need N*N+BDSPAC)
                   1782: *
                   1783:                      CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ), VT,
                   1784:      $                            LDVT, WORK( IU ), LDWRKU, DUM, 1,
                   1785:      $                            WORK( IWORK ), INFO )
                   1786: *
                   1787: *                    Multiply Q in U by left singular vectors of R in
                   1788: *                    WORK(IU), storing result in A
                   1789: *                    (Workspace: need N*N)
                   1790: *
                   1791:                      CALL DGEMM( 'N', 'N', M, N, N, ONE, U, LDU,
                   1792:      $                           WORK( IU ), LDWRKU, ZERO, A, LDA )
                   1793: *
                   1794: *                    Copy left singular vectors of A from A to U
                   1795: *
                   1796:                      CALL DLACPY( 'F', M, N, A, LDA, U, LDU )
                   1797: *
                   1798:                   ELSE
                   1799: *
                   1800: *                    Insufficient workspace for a fast algorithm
                   1801: *
                   1802:                      ITAU = 1
                   1803:                      IWORK = ITAU + N
                   1804: *
                   1805: *                    Compute A=Q*R, copying result to U
                   1806: *                    (Workspace: need 2*N, prefer N+N*NB)
                   1807: *
                   1808:                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
                   1809:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1810:                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
                   1811: *
                   1812: *                    Generate Q in U
                   1813: *                    (Workspace: need N+M, prefer N+M*NB)
                   1814: *
                   1815:                      CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
                   1816:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1817: *
                   1818: *                    Copy R from A to VT, zeroing out below it
                   1819: *
                   1820:                      CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )
                   1821:                      IF( N.GT.1 )
                   1822:      $                  CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
                   1823:      $                               VT( 2, 1 ), LDVT )
                   1824:                      IE = ITAU
                   1825:                      ITAUQ = IE + N
                   1826:                      ITAUP = ITAUQ + N
                   1827:                      IWORK = ITAUP + N
                   1828: *
                   1829: *                    Bidiagonalize R in VT
                   1830: *                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
                   1831: *
                   1832:                      CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),
                   1833:      $                            WORK( ITAUQ ), WORK( ITAUP ),
                   1834:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1835: *
                   1836: *                    Multiply Q in U by left bidiagonalizing vectors
                   1837: *                    in VT
                   1838: *                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
                   1839: *
                   1840:                      CALL DORMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
                   1841:      $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
                   1842:      $                            LWORK-IWORK+1, IERR )
                   1843: *
                   1844: *                    Generate right bidiagonalizing vectors in VT
                   1845: *                    (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
                   1846: *
                   1847:                      CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
                   1848:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1849:                      IWORK = IE + N
                   1850: *
                   1851: *                    Perform bidiagonal QR iteration, computing left
                   1852: *                    singular vectors of A in U and computing right
                   1853: *                    singular vectors of A in VT
                   1854: *                    (Workspace: need BDSPAC)
                   1855: *
                   1856:                      CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), VT,
                   1857:      $                            LDVT, U, LDU, DUM, 1, WORK( IWORK ),
                   1858:      $                            INFO )
                   1859: *
                   1860:                   END IF
                   1861: *
                   1862:                END IF
                   1863: *
                   1864:             END IF
                   1865: *
                   1866:          ELSE
                   1867: *
                   1868: *           M .LT. MNTHR
                   1869: *
                   1870: *           Path 10 (M at least N, but not much larger)
                   1871: *           Reduce to bidiagonal form without QR decomposition
                   1872: *
                   1873:             IE = 1
                   1874:             ITAUQ = IE + N
                   1875:             ITAUP = ITAUQ + N
                   1876:             IWORK = ITAUP + N
                   1877: *
                   1878: *           Bidiagonalize A
                   1879: *           (Workspace: need 3*N+M, prefer 3*N+(M+N)*NB)
                   1880: *
                   1881:             CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
                   1882:      $                   WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
                   1883:      $                   IERR )
                   1884:             IF( WNTUAS ) THEN
                   1885: *
                   1886: *              If left singular vectors desired in U, copy result to U
                   1887: *              and generate left bidiagonalizing vectors in U
                   1888: *              (Workspace: need 3*N+NCU, prefer 3*N+NCU*NB)
                   1889: *
                   1890:                CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
                   1891:                IF( WNTUS )
                   1892:      $            NCU = N
                   1893:                IF( WNTUA )
                   1894:      $            NCU = M
                   1895:                CALL DORGBR( 'Q', M, NCU, N, U, LDU, WORK( ITAUQ ),
                   1896:      $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1897:             END IF
                   1898:             IF( WNTVAS ) THEN
                   1899: *
                   1900: *              If right singular vectors desired in VT, copy result to
                   1901: *              VT and generate right bidiagonalizing vectors in VT
                   1902: *              (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
                   1903: *
                   1904:                CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )
                   1905:                CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
                   1906:      $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1907:             END IF
                   1908:             IF( WNTUO ) THEN
                   1909: *
                   1910: *              If left singular vectors desired in A, generate left
                   1911: *              bidiagonalizing vectors in A
                   1912: *              (Workspace: need 4*N, prefer 3*N+N*NB)
                   1913: *
                   1914:                CALL DORGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
                   1915:      $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1916:             END IF
                   1917:             IF( WNTVO ) THEN
                   1918: *
                   1919: *              If right singular vectors desired in A, generate right
                   1920: *              bidiagonalizing vectors in A
                   1921: *              (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
                   1922: *
                   1923:                CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
                   1924:      $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
                   1925:             END IF
                   1926:             IWORK = IE + N
                   1927:             IF( WNTUAS .OR. WNTUO )
                   1928:      $         NRU = M
                   1929:             IF( WNTUN )
                   1930:      $         NRU = 0
                   1931:             IF( WNTVAS .OR. WNTVO )
                   1932:      $         NCVT = N
                   1933:             IF( WNTVN )
                   1934:      $         NCVT = 0
                   1935:             IF( ( .NOT.WNTUO ) .AND. ( .NOT.WNTVO ) ) THEN
                   1936: *
                   1937: *              Perform bidiagonal QR iteration, if desired, computing
                   1938: *              left singular vectors in U and computing right singular
                   1939: *              vectors in VT
                   1940: *              (Workspace: need BDSPAC)
                   1941: *
                   1942:                CALL DBDSQR( 'U', N, NCVT, NRU, 0, S, WORK( IE ), VT,
                   1943:      $                      LDVT, U, LDU, DUM, 1, WORK( IWORK ), INFO )
                   1944:             ELSE IF( ( .NOT.WNTUO ) .AND. WNTVO ) THEN
                   1945: *
                   1946: *              Perform bidiagonal QR iteration, if desired, computing
                   1947: *              left singular vectors in U and computing right singular
                   1948: *              vectors in A
                   1949: *              (Workspace: need BDSPAC)
                   1950: *
                   1951:                CALL DBDSQR( 'U', N, NCVT, NRU, 0, S, WORK( IE ), A, LDA,
                   1952:      $                      U, LDU, DUM, 1, WORK( IWORK ), INFO )
                   1953:             ELSE
                   1954: *
                   1955: *              Perform bidiagonal QR iteration, if desired, computing
                   1956: *              left singular vectors in A and computing right singular
                   1957: *              vectors in VT
                   1958: *              (Workspace: need BDSPAC)
                   1959: *
                   1960:                CALL DBDSQR( 'U', N, NCVT, NRU, 0, S, WORK( IE ), VT,
                   1961:      $                      LDVT, A, LDA, DUM, 1, WORK( IWORK ), INFO )
                   1962:             END IF
                   1963: *
                   1964:          END IF
                   1965: *
                   1966:       ELSE
                   1967: *
                   1968: *        A has more columns than rows. If A has sufficiently more
                   1969: *        columns than rows, first reduce using the LQ decomposition (if
                   1970: *        sufficient workspace available)
                   1971: *
                   1972:          IF( N.GE.MNTHR ) THEN
                   1973: *
                   1974:             IF( WNTVN ) THEN
                   1975: *
                   1976: *              Path 1t(N much larger than M, JOBVT='N')
                   1977: *              No right singular vectors to be computed
                   1978: *
                   1979:                ITAU = 1
                   1980:                IWORK = ITAU + M
                   1981: *
                   1982: *              Compute A=L*Q
                   1983: *              (Workspace: need 2*M, prefer M+M*NB)
                   1984: *
                   1985:                CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
                   1986:      $                      LWORK-IWORK+1, IERR )
                   1987: *
                   1988: *              Zero out above L
                   1989: *
                   1990:                CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ), LDA )
                   1991:                IE = 1
                   1992:                ITAUQ = IE + M
                   1993:                ITAUP = ITAUQ + M
                   1994:                IWORK = ITAUP + M
                   1995: *
                   1996: *              Bidiagonalize L in A
                   1997: *              (Workspace: need 4*M, prefer 3*M+2*M*NB)
                   1998: *
                   1999:                CALL DGEBRD( M, M, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
                   2000:      $                      WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
                   2001:      $                      IERR )
                   2002:                IF( WNTUO .OR. WNTUAS ) THEN
                   2003: *
                   2004: *                 If left singular vectors desired, generate Q
                   2005: *                 (Workspace: need 4*M, prefer 3*M+M*NB)
                   2006: *
                   2007:                   CALL DORGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
                   2008:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2009:                END IF
                   2010:                IWORK = IE + M
                   2011:                NRU = 0
                   2012:                IF( WNTUO .OR. WNTUAS )
                   2013:      $            NRU = M
                   2014: *
                   2015: *              Perform bidiagonal QR iteration, computing left singular
                   2016: *              vectors of A in A if desired
                   2017: *              (Workspace: need BDSPAC)
                   2018: *
                   2019:                CALL DBDSQR( 'U', M, 0, NRU, 0, S, WORK( IE ), DUM, 1, A,
                   2020:      $                      LDA, DUM, 1, WORK( IWORK ), INFO )
                   2021: *
                   2022: *              If left singular vectors desired in U, copy them there
                   2023: *
                   2024:                IF( WNTUAS )
                   2025:      $            CALL DLACPY( 'F', M, M, A, LDA, U, LDU )
                   2026: *
                   2027:             ELSE IF( WNTVO .AND. WNTUN ) THEN
                   2028: *
                   2029: *              Path 2t(N much larger than M, JOBU='N', JOBVT='O')
                   2030: *              M right singular vectors to be overwritten on A and
                   2031: *              no left singular vectors to be computed
                   2032: *
                   2033:                IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN
                   2034: *
                   2035: *                 Sufficient workspace for a fast algorithm
                   2036: *
                   2037:                   IR = 1
                   2038:                   IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+LDA*M ) THEN
                   2039: *
                   2040: *                    WORK(IU) is LDA by N and WORK(IR) is LDA by M
                   2041: *
                   2042:                      LDWRKU = LDA
                   2043:                      CHUNK = N
                   2044:                      LDWRKR = LDA
                   2045:                   ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+M*M ) THEN
                   2046: *
                   2047: *                    WORK(IU) is LDA by N and WORK(IR) is M by M
                   2048: *
                   2049:                      LDWRKU = LDA
                   2050:                      CHUNK = N
                   2051:                      LDWRKR = M
                   2052:                   ELSE
                   2053: *
                   2054: *                    WORK(IU) is M by CHUNK and WORK(IR) is M by M
                   2055: *
                   2056:                      LDWRKU = M
                   2057:                      CHUNK = ( LWORK-M*M-M ) / M
                   2058:                      LDWRKR = M
                   2059:                   END IF
                   2060:                   ITAU = IR + LDWRKR*M
                   2061:                   IWORK = ITAU + M
                   2062: *
                   2063: *                 Compute A=L*Q
                   2064: *                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
                   2065: *
                   2066:                   CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
                   2067:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2068: *
                   2069: *                 Copy L to WORK(IR) and zero out above it
                   2070: *
                   2071:                   CALL DLACPY( 'L', M, M, A, LDA, WORK( IR ), LDWRKR )
                   2072:                   CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
                   2073:      $                         WORK( IR+LDWRKR ), LDWRKR )
                   2074: *
                   2075: *                 Generate Q in A
                   2076: *                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
                   2077: *
                   2078:                   CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
                   2079:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2080:                   IE = ITAU
                   2081:                   ITAUQ = IE + M
                   2082:                   ITAUP = ITAUQ + M
                   2083:                   IWORK = ITAUP + M
                   2084: *
                   2085: *                 Bidiagonalize L in WORK(IR)
                   2086: *                 (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
                   2087: *
                   2088:                   CALL DGEBRD( M, M, WORK( IR ), LDWRKR, S, WORK( IE ),
                   2089:      $                         WORK( ITAUQ ), WORK( ITAUP ),
                   2090:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2091: *
                   2092: *                 Generate right vectors bidiagonalizing L
                   2093: *                 (Workspace: need M*M+4*M-1, prefer M*M+3*M+(M-1)*NB)
                   2094: *
                   2095:                   CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
                   2096:      $                         WORK( ITAUP ), WORK( IWORK ),
                   2097:      $                         LWORK-IWORK+1, IERR )
                   2098:                   IWORK = IE + M
                   2099: *
                   2100: *                 Perform bidiagonal QR iteration, computing right
                   2101: *                 singular vectors of L in WORK(IR)
                   2102: *                 (Workspace: need M*M+BDSPAC)
                   2103: *
                   2104:                   CALL DBDSQR( 'U', M, M, 0, 0, S, WORK( IE ),
                   2105:      $                         WORK( IR ), LDWRKR, DUM, 1, DUM, 1,
                   2106:      $                         WORK( IWORK ), INFO )
                   2107:                   IU = IE + M
                   2108: *
                   2109: *                 Multiply right singular vectors of L in WORK(IR) by Q
                   2110: *                 in A, storing result in WORK(IU) and copying to A
                   2111: *                 (Workspace: need M*M+2*M, prefer M*M+M*N+M)
                   2112: *
                   2113:                   DO 30 I = 1, N, CHUNK
                   2114:                      BLK = MIN( N-I+1, CHUNK )
                   2115:                      CALL DGEMM( 'N', 'N', M, BLK, M, ONE, WORK( IR ),
                   2116:      $                           LDWRKR, A( 1, I ), LDA, ZERO,
                   2117:      $                           WORK( IU ), LDWRKU )
                   2118:                      CALL DLACPY( 'F', M, BLK, WORK( IU ), LDWRKU,
                   2119:      $                            A( 1, I ), LDA )
                   2120:    30             CONTINUE
                   2121: *
                   2122:                ELSE
                   2123: *
                   2124: *                 Insufficient workspace for a fast algorithm
                   2125: *
                   2126:                   IE = 1
                   2127:                   ITAUQ = IE + M
                   2128:                   ITAUP = ITAUQ + M
                   2129:                   IWORK = ITAUP + M
                   2130: *
                   2131: *                 Bidiagonalize A
                   2132: *                 (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)
                   2133: *
                   2134:                   CALL DGEBRD( M, N, A, LDA, S, WORK( IE ),
                   2135:      $                         WORK( ITAUQ ), WORK( ITAUP ),
                   2136:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2137: *
                   2138: *                 Generate right vectors bidiagonalizing A
                   2139: *                 (Workspace: need 4*M, prefer 3*M+M*NB)
                   2140: *
                   2141:                   CALL DORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
                   2142:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2143:                   IWORK = IE + M
                   2144: *
                   2145: *                 Perform bidiagonal QR iteration, computing right
                   2146: *                 singular vectors of A in A
                   2147: *                 (Workspace: need BDSPAC)
                   2148: *
                   2149:                   CALL DBDSQR( 'L', M, N, 0, 0, S, WORK( IE ), A, LDA,
                   2150:      $                         DUM, 1, DUM, 1, WORK( IWORK ), INFO )
                   2151: *
                   2152:                END IF
                   2153: *
                   2154:             ELSE IF( WNTVO .AND. WNTUAS ) THEN
                   2155: *
                   2156: *              Path 3t(N much larger than M, JOBU='S' or 'A', JOBVT='O')
                   2157: *              M right singular vectors to be overwritten on A and
                   2158: *              M left singular vectors to be computed in U
                   2159: *
                   2160:                IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN
                   2161: *
                   2162: *                 Sufficient workspace for a fast algorithm
                   2163: *
                   2164:                   IR = 1
                   2165:                   IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+LDA*M ) THEN
                   2166: *
                   2167: *                    WORK(IU) is LDA by N and WORK(IR) is LDA by M
                   2168: *
                   2169:                      LDWRKU = LDA
                   2170:                      CHUNK = N
                   2171:                      LDWRKR = LDA
                   2172:                   ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+M*M ) THEN
                   2173: *
                   2174: *                    WORK(IU) is LDA by N and WORK(IR) is M by M
                   2175: *
                   2176:                      LDWRKU = LDA
                   2177:                      CHUNK = N
                   2178:                      LDWRKR = M
                   2179:                   ELSE
                   2180: *
                   2181: *                    WORK(IU) is M by CHUNK and WORK(IR) is M by M
                   2182: *
                   2183:                      LDWRKU = M
                   2184:                      CHUNK = ( LWORK-M*M-M ) / M
                   2185:                      LDWRKR = M
                   2186:                   END IF
                   2187:                   ITAU = IR + LDWRKR*M
                   2188:                   IWORK = ITAU + M
                   2189: *
                   2190: *                 Compute A=L*Q
                   2191: *                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
                   2192: *
                   2193:                   CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
                   2194:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2195: *
                   2196: *                 Copy L to U, zeroing about above it
                   2197: *
                   2198:                   CALL DLACPY( 'L', M, M, A, LDA, U, LDU )
                   2199:                   CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),
                   2200:      $                         LDU )
                   2201: *
                   2202: *                 Generate Q in A
                   2203: *                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
                   2204: *
                   2205:                   CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
                   2206:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2207:                   IE = ITAU
                   2208:                   ITAUQ = IE + M
                   2209:                   ITAUP = ITAUQ + M
                   2210:                   IWORK = ITAUP + M
                   2211: *
                   2212: *                 Bidiagonalize L in U, copying result to WORK(IR)
                   2213: *                 (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
                   2214: *
                   2215:                   CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),
                   2216:      $                         WORK( ITAUQ ), WORK( ITAUP ),
                   2217:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2218:                   CALL DLACPY( 'U', M, M, U, LDU, WORK( IR ), LDWRKR )
                   2219: *
                   2220: *                 Generate right vectors bidiagonalizing L in WORK(IR)
                   2221: *                 (Workspace: need M*M+4*M-1, prefer M*M+3*M+(M-1)*NB)
                   2222: *
                   2223:                   CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
                   2224:      $                         WORK( ITAUP ), WORK( IWORK ),
                   2225:      $                         LWORK-IWORK+1, IERR )
                   2226: *
                   2227: *                 Generate left vectors bidiagonalizing L in U
                   2228: *                 (Workspace: need M*M+4*M, prefer M*M+3*M+M*NB)
                   2229: *
                   2230:                   CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
                   2231:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2232:                   IWORK = IE + M
                   2233: *
                   2234: *                 Perform bidiagonal QR iteration, computing left
                   2235: *                 singular vectors of L in U, and computing right
                   2236: *                 singular vectors of L in WORK(IR)
                   2237: *                 (Workspace: need M*M+BDSPAC)
                   2238: *
                   2239:                   CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
                   2240:      $                         WORK( IR ), LDWRKR, U, LDU, DUM, 1,
                   2241:      $                         WORK( IWORK ), INFO )
                   2242:                   IU = IE + M
                   2243: *
                   2244: *                 Multiply right singular vectors of L in WORK(IR) by Q
                   2245: *                 in A, storing result in WORK(IU) and copying to A
                   2246: *                 (Workspace: need M*M+2*M, prefer M*M+M*N+M))
                   2247: *
                   2248:                   DO 40 I = 1, N, CHUNK
                   2249:                      BLK = MIN( N-I+1, CHUNK )
                   2250:                      CALL DGEMM( 'N', 'N', M, BLK, M, ONE, WORK( IR ),
                   2251:      $                           LDWRKR, A( 1, I ), LDA, ZERO,
                   2252:      $                           WORK( IU ), LDWRKU )
                   2253:                      CALL DLACPY( 'F', M, BLK, WORK( IU ), LDWRKU,
                   2254:      $                            A( 1, I ), LDA )
                   2255:    40             CONTINUE
                   2256: *
                   2257:                ELSE
                   2258: *
                   2259: *                 Insufficient workspace for a fast algorithm
                   2260: *
                   2261:                   ITAU = 1
                   2262:                   IWORK = ITAU + M
                   2263: *
                   2264: *                 Compute A=L*Q
                   2265: *                 (Workspace: need 2*M, prefer M+M*NB)
                   2266: *
                   2267:                   CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
                   2268:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2269: *
                   2270: *                 Copy L to U, zeroing out above it
                   2271: *
                   2272:                   CALL DLACPY( 'L', M, M, A, LDA, U, LDU )
                   2273:                   CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),
                   2274:      $                         LDU )
                   2275: *
                   2276: *                 Generate Q in A
                   2277: *                 (Workspace: need 2*M, prefer M+M*NB)
                   2278: *
                   2279:                   CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
                   2280:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2281:                   IE = ITAU
                   2282:                   ITAUQ = IE + M
                   2283:                   ITAUP = ITAUQ + M
                   2284:                   IWORK = ITAUP + M
                   2285: *
                   2286: *                 Bidiagonalize L in U
                   2287: *                 (Workspace: need 4*M, prefer 3*M+2*M*NB)
                   2288: *
                   2289:                   CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),
                   2290:      $                         WORK( ITAUQ ), WORK( ITAUP ),
                   2291:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2292: *
                   2293: *                 Multiply right vectors bidiagonalizing L by Q in A
                   2294: *                 (Workspace: need 3*M+N, prefer 3*M+N*NB)
                   2295: *
                   2296:                   CALL DORMBR( 'P', 'L', 'T', M, N, M, U, LDU,
                   2297:      $                         WORK( ITAUP ), A, LDA, WORK( IWORK ),
                   2298:      $                         LWORK-IWORK+1, IERR )
                   2299: *
                   2300: *                 Generate left vectors bidiagonalizing L in U
                   2301: *                 (Workspace: need 4*M, prefer 3*M+M*NB)
                   2302: *
                   2303:                   CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
                   2304:      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2305:                   IWORK = IE + M
                   2306: *
                   2307: *                 Perform bidiagonal QR iteration, computing left
                   2308: *                 singular vectors of A in U and computing right
                   2309: *                 singular vectors of A in A
                   2310: *                 (Workspace: need BDSPAC)
                   2311: *
                   2312:                   CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), A, LDA,
                   2313:      $                         U, LDU, DUM, 1, WORK( IWORK ), INFO )
                   2314: *
                   2315:                END IF
                   2316: *
                   2317:             ELSE IF( WNTVS ) THEN
                   2318: *
                   2319:                IF( WNTUN ) THEN
                   2320: *
                   2321: *                 Path 4t(N much larger than M, JOBU='N', JOBVT='S')
                   2322: *                 M right singular vectors to be computed in VT and
                   2323: *                 no left singular vectors to be computed
                   2324: *
                   2325:                   IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN
                   2326: *
                   2327: *                    Sufficient workspace for a fast algorithm
                   2328: *
                   2329:                      IR = 1
                   2330:                      IF( LWORK.GE.WRKBL+LDA*M ) THEN
                   2331: *
                   2332: *                       WORK(IR) is LDA by M
                   2333: *
                   2334:                         LDWRKR = LDA
                   2335:                      ELSE
                   2336: *
                   2337: *                       WORK(IR) is M by M
                   2338: *
                   2339:                         LDWRKR = M
                   2340:                      END IF
                   2341:                      ITAU = IR + LDWRKR*M
                   2342:                      IWORK = ITAU + M
                   2343: *
                   2344: *                    Compute A=L*Q
                   2345: *                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
                   2346: *
                   2347:                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
                   2348:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2349: *
                   2350: *                    Copy L to WORK(IR), zeroing out above it
                   2351: *
                   2352:                      CALL DLACPY( 'L', M, M, A, LDA, WORK( IR ),
                   2353:      $                            LDWRKR )
                   2354:                      CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
                   2355:      $                            WORK( IR+LDWRKR ), LDWRKR )
                   2356: *
                   2357: *                    Generate Q in A
                   2358: *                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
                   2359: *
                   2360:                      CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
                   2361:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2362:                      IE = ITAU
                   2363:                      ITAUQ = IE + M
                   2364:                      ITAUP = ITAUQ + M
                   2365:                      IWORK = ITAUP + M
                   2366: *
                   2367: *                    Bidiagonalize L in WORK(IR)
                   2368: *                    (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
                   2369: *
                   2370:                      CALL DGEBRD( M, M, WORK( IR ), LDWRKR, S,
                   2371:      $                            WORK( IE ), WORK( ITAUQ ),
                   2372:      $                            WORK( ITAUP ), WORK( IWORK ),
                   2373:      $                            LWORK-IWORK+1, IERR )
                   2374: *
                   2375: *                    Generate right vectors bidiagonalizing L in
                   2376: *                    WORK(IR)
                   2377: *                    (Workspace: need M*M+4*M, prefer M*M+3*M+(M-1)*NB)
                   2378: *
                   2379:                      CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
                   2380:      $                            WORK( ITAUP ), WORK( IWORK ),
                   2381:      $                            LWORK-IWORK+1, IERR )
                   2382:                      IWORK = IE + M
                   2383: *
                   2384: *                    Perform bidiagonal QR iteration, computing right
                   2385: *                    singular vectors of L in WORK(IR)
                   2386: *                    (Workspace: need M*M+BDSPAC)
                   2387: *
                   2388:                      CALL DBDSQR( 'U', M, M, 0, 0, S, WORK( IE ),
                   2389:      $                            WORK( IR ), LDWRKR, DUM, 1, DUM, 1,
                   2390:      $                            WORK( IWORK ), INFO )
                   2391: *
                   2392: *                    Multiply right singular vectors of L in WORK(IR) by
                   2393: *                    Q in A, storing result in VT
                   2394: *                    (Workspace: need M*M)
                   2395: *
                   2396:                      CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IR ),
                   2397:      $                           LDWRKR, A, LDA, ZERO, VT, LDVT )
                   2398: *
                   2399:                   ELSE
                   2400: *
                   2401: *                    Insufficient workspace for a fast algorithm
                   2402: *
                   2403:                      ITAU = 1
                   2404:                      IWORK = ITAU + M
                   2405: *
                   2406: *                    Compute A=L*Q
                   2407: *                    (Workspace: need 2*M, prefer M+M*NB)
                   2408: *
                   2409:                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
                   2410:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2411: *
                   2412: *                    Copy result to VT
                   2413: *
                   2414:                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
                   2415: *
                   2416: *                    Generate Q in VT
                   2417: *                    (Workspace: need 2*M, prefer M+M*NB)
                   2418: *
                   2419:                      CALL DORGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
                   2420:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2421:                      IE = ITAU
                   2422:                      ITAUQ = IE + M
                   2423:                      ITAUP = ITAUQ + M
                   2424:                      IWORK = ITAUP + M
                   2425: *
                   2426: *                    Zero out above L in A
                   2427: *
                   2428:                      CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),
                   2429:      $                            LDA )
                   2430: *
                   2431: *                    Bidiagonalize L in A
                   2432: *                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
                   2433: *
                   2434:                      CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),
                   2435:      $                            WORK( ITAUQ ), WORK( ITAUP ),
                   2436:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2437: *
                   2438: *                    Multiply right vectors bidiagonalizing L by Q in VT
                   2439: *                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
                   2440: *
                   2441:                      CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,
                   2442:      $                            WORK( ITAUP ), VT, LDVT,
                   2443:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2444:                      IWORK = IE + M
                   2445: *
                   2446: *                    Perform bidiagonal QR iteration, computing right
                   2447: *                    singular vectors of A in VT
                   2448: *                    (Workspace: need BDSPAC)
                   2449: *
                   2450:                      CALL DBDSQR( 'U', M, N, 0, 0, S, WORK( IE ), VT,
                   2451:      $                            LDVT, DUM, 1, DUM, 1, WORK( IWORK ),
                   2452:      $                            INFO )
                   2453: *
                   2454:                   END IF
                   2455: *
                   2456:                ELSE IF( WNTUO ) THEN
                   2457: *
                   2458: *                 Path 5t(N much larger than M, JOBU='O', JOBVT='S')
                   2459: *                 M right singular vectors to be computed in VT and
                   2460: *                 M left singular vectors to be overwritten on A
                   2461: *
                   2462:                   IF( LWORK.GE.2*M*M+MAX( 4*M, BDSPAC ) ) THEN
                   2463: *
                   2464: *                    Sufficient workspace for a fast algorithm
                   2465: *
                   2466:                      IU = 1
                   2467:                      IF( LWORK.GE.WRKBL+2*LDA*M ) THEN
                   2468: *
                   2469: *                       WORK(IU) is LDA by M and WORK(IR) is LDA by M
                   2470: *
                   2471:                         LDWRKU = LDA
                   2472:                         IR = IU + LDWRKU*M
                   2473:                         LDWRKR = LDA
                   2474:                      ELSE IF( LWORK.GE.WRKBL+( LDA+M )*M ) THEN
                   2475: *
                   2476: *                       WORK(IU) is LDA by M and WORK(IR) is M by M
                   2477: *
                   2478:                         LDWRKU = LDA
                   2479:                         IR = IU + LDWRKU*M
                   2480:                         LDWRKR = M
                   2481:                      ELSE
                   2482: *
                   2483: *                       WORK(IU) is M by M and WORK(IR) is M by M
                   2484: *
                   2485:                         LDWRKU = M
                   2486:                         IR = IU + LDWRKU*M
                   2487:                         LDWRKR = M
                   2488:                      END IF
                   2489:                      ITAU = IR + LDWRKR*M
                   2490:                      IWORK = ITAU + M
                   2491: *
                   2492: *                    Compute A=L*Q
                   2493: *                    (Workspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)
                   2494: *
                   2495:                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
                   2496:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2497: *
                   2498: *                    Copy L to WORK(IU), zeroing out below it
                   2499: *
                   2500:                      CALL DLACPY( 'L', M, M, A, LDA, WORK( IU ),
                   2501:      $                            LDWRKU )
                   2502:                      CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
                   2503:      $                            WORK( IU+LDWRKU ), LDWRKU )
                   2504: *
                   2505: *                    Generate Q in A
                   2506: *                    (Workspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)
                   2507: *
                   2508:                      CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
                   2509:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2510:                      IE = ITAU
                   2511:                      ITAUQ = IE + M
                   2512:                      ITAUP = ITAUQ + M
                   2513:                      IWORK = ITAUP + M
                   2514: *
                   2515: *                    Bidiagonalize L in WORK(IU), copying result to
                   2516: *                    WORK(IR)
                   2517: *                    (Workspace: need 2*M*M+4*M,
                   2518: *                                prefer 2*M*M+3*M+2*M*NB)
                   2519: *
                   2520:                      CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,
                   2521:      $                            WORK( IE ), WORK( ITAUQ ),
                   2522:      $                            WORK( ITAUP ), WORK( IWORK ),
                   2523:      $                            LWORK-IWORK+1, IERR )
                   2524:                      CALL DLACPY( 'L', M, M, WORK( IU ), LDWRKU,
                   2525:      $                            WORK( IR ), LDWRKR )
                   2526: *
                   2527: *                    Generate right bidiagonalizing vectors in WORK(IU)
                   2528: *                    (Workspace: need 2*M*M+4*M-1,
                   2529: *                                prefer 2*M*M+3*M+(M-1)*NB)
                   2530: *
                   2531:                      CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
                   2532:      $                            WORK( ITAUP ), WORK( IWORK ),
                   2533:      $                            LWORK-IWORK+1, IERR )
                   2534: *
                   2535: *                    Generate left bidiagonalizing vectors in WORK(IR)
                   2536: *                    (Workspace: need 2*M*M+4*M, prefer 2*M*M+3*M+M*NB)
                   2537: *
                   2538:                      CALL DORGBR( 'Q', M, M, M, WORK( IR ), LDWRKR,
                   2539:      $                            WORK( ITAUQ ), WORK( IWORK ),
                   2540:      $                            LWORK-IWORK+1, IERR )
                   2541:                      IWORK = IE + M
                   2542: *
                   2543: *                    Perform bidiagonal QR iteration, computing left
                   2544: *                    singular vectors of L in WORK(IR) and computing
                   2545: *                    right singular vectors of L in WORK(IU)
                   2546: *                    (Workspace: need 2*M*M+BDSPAC)
                   2547: *
                   2548:                      CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
                   2549:      $                            WORK( IU ), LDWRKU, WORK( IR ),
                   2550:      $                            LDWRKR, DUM, 1, WORK( IWORK ), INFO )
                   2551: *
                   2552: *                    Multiply right singular vectors of L in WORK(IU) by
                   2553: *                    Q in A, storing result in VT
                   2554: *                    (Workspace: need M*M)
                   2555: *
                   2556:                      CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),
                   2557:      $                           LDWRKU, A, LDA, ZERO, VT, LDVT )
                   2558: *
                   2559: *                    Copy left singular vectors of L to A
                   2560: *                    (Workspace: need M*M)
                   2561: *
                   2562:                      CALL DLACPY( 'F', M, M, WORK( IR ), LDWRKR, A,
                   2563:      $                            LDA )
                   2564: *
                   2565:                   ELSE
                   2566: *
                   2567: *                    Insufficient workspace for a fast algorithm
                   2568: *
                   2569:                      ITAU = 1
                   2570:                      IWORK = ITAU + M
                   2571: *
                   2572: *                    Compute A=L*Q, copying result to VT
                   2573: *                    (Workspace: need 2*M, prefer M+M*NB)
                   2574: *
                   2575:                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
                   2576:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2577:                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
                   2578: *
                   2579: *                    Generate Q in VT
                   2580: *                    (Workspace: need 2*M, prefer M+M*NB)
                   2581: *
                   2582:                      CALL DORGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
                   2583:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2584:                      IE = ITAU
                   2585:                      ITAUQ = IE + M
                   2586:                      ITAUP = ITAUQ + M
                   2587:                      IWORK = ITAUP + M
                   2588: *
                   2589: *                    Zero out above L in A
                   2590: *
                   2591:                      CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),
                   2592:      $                            LDA )
                   2593: *
                   2594: *                    Bidiagonalize L in A
                   2595: *                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
                   2596: *
                   2597:                      CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),
                   2598:      $                            WORK( ITAUQ ), WORK( ITAUP ),
                   2599:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2600: *
                   2601: *                    Multiply right vectors bidiagonalizing L by Q in VT
                   2602: *                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
                   2603: *
                   2604:                      CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,
                   2605:      $                            WORK( ITAUP ), VT, LDVT,
                   2606:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2607: *
                   2608: *                    Generate left bidiagonalizing vectors of L in A
                   2609: *                    (Workspace: need 4*M, prefer 3*M+M*NB)
                   2610: *
                   2611:                      CALL DORGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
                   2612:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2613:                      IWORK = IE + M
                   2614: *
                   2615: *                    Perform bidiagonal QR iteration, compute left
                   2616: *                    singular vectors of A in A and compute right
                   2617: *                    singular vectors of A in VT
                   2618: *                    (Workspace: need BDSPAC)
                   2619: *
                   2620:                      CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,
                   2621:      $                            LDVT, A, LDA, DUM, 1, WORK( IWORK ),
                   2622:      $                            INFO )
                   2623: *
                   2624:                   END IF
                   2625: *
                   2626:                ELSE IF( WNTUAS ) THEN
                   2627: *
                   2628: *                 Path 6t(N much larger than M, JOBU='S' or 'A',
                   2629: *                         JOBVT='S')
                   2630: *                 M right singular vectors to be computed in VT and
                   2631: *                 M left singular vectors to be computed in U
                   2632: *
                   2633:                   IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN
                   2634: *
                   2635: *                    Sufficient workspace for a fast algorithm
                   2636: *
                   2637:                      IU = 1
                   2638:                      IF( LWORK.GE.WRKBL+LDA*M ) THEN
                   2639: *
                   2640: *                       WORK(IU) is LDA by N
                   2641: *
                   2642:                         LDWRKU = LDA
                   2643:                      ELSE
                   2644: *
                   2645: *                       WORK(IU) is LDA by M
                   2646: *
                   2647:                         LDWRKU = M
                   2648:                      END IF
                   2649:                      ITAU = IU + LDWRKU*M
                   2650:                      IWORK = ITAU + M
                   2651: *
                   2652: *                    Compute A=L*Q
                   2653: *                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
                   2654: *
                   2655:                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
                   2656:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2657: *
                   2658: *                    Copy L to WORK(IU), zeroing out above it
                   2659: *
                   2660:                      CALL DLACPY( 'L', M, M, A, LDA, WORK( IU ),
                   2661:      $                            LDWRKU )
                   2662:                      CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
                   2663:      $                            WORK( IU+LDWRKU ), LDWRKU )
                   2664: *
                   2665: *                    Generate Q in A
                   2666: *                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
                   2667: *
                   2668:                      CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
                   2669:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2670:                      IE = ITAU
                   2671:                      ITAUQ = IE + M
                   2672:                      ITAUP = ITAUQ + M
                   2673:                      IWORK = ITAUP + M
                   2674: *
                   2675: *                    Bidiagonalize L in WORK(IU), copying result to U
                   2676: *                    (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
                   2677: *
                   2678:                      CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,
                   2679:      $                            WORK( IE ), WORK( ITAUQ ),
                   2680:      $                            WORK( ITAUP ), WORK( IWORK ),
                   2681:      $                            LWORK-IWORK+1, IERR )
                   2682:                      CALL DLACPY( 'L', M, M, WORK( IU ), LDWRKU, U,
                   2683:      $                            LDU )
                   2684: *
                   2685: *                    Generate right bidiagonalizing vectors in WORK(IU)
                   2686: *                    (Workspace: need M*M+4*M-1,
                   2687: *                                prefer M*M+3*M+(M-1)*NB)
                   2688: *
                   2689:                      CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
                   2690:      $                            WORK( ITAUP ), WORK( IWORK ),
                   2691:      $                            LWORK-IWORK+1, IERR )
                   2692: *
                   2693: *                    Generate left bidiagonalizing vectors in U
                   2694: *                    (Workspace: need M*M+4*M, prefer M*M+3*M+M*NB)
                   2695: *
                   2696:                      CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
                   2697:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2698:                      IWORK = IE + M
                   2699: *
                   2700: *                    Perform bidiagonal QR iteration, computing left
                   2701: *                    singular vectors of L in U and computing right
                   2702: *                    singular vectors of L in WORK(IU)
                   2703: *                    (Workspace: need M*M+BDSPAC)
                   2704: *
                   2705:                      CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
                   2706:      $                            WORK( IU ), LDWRKU, U, LDU, DUM, 1,
                   2707:      $                            WORK( IWORK ), INFO )
                   2708: *
                   2709: *                    Multiply right singular vectors of L in WORK(IU) by
                   2710: *                    Q in A, storing result in VT
                   2711: *                    (Workspace: need M*M)
                   2712: *
                   2713:                      CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),
                   2714:      $                           LDWRKU, A, LDA, ZERO, VT, LDVT )
                   2715: *
                   2716:                   ELSE
                   2717: *
                   2718: *                    Insufficient workspace for a fast algorithm
                   2719: *
                   2720:                      ITAU = 1
                   2721:                      IWORK = ITAU + M
                   2722: *
                   2723: *                    Compute A=L*Q, copying result to VT
                   2724: *                    (Workspace: need 2*M, prefer M+M*NB)
                   2725: *
                   2726:                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
                   2727:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2728:                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
                   2729: *
                   2730: *                    Generate Q in VT
                   2731: *                    (Workspace: need 2*M, prefer M+M*NB)
                   2732: *
                   2733:                      CALL DORGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
                   2734:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2735: *
                   2736: *                    Copy L to U, zeroing out above it
                   2737: *
                   2738:                      CALL DLACPY( 'L', M, M, A, LDA, U, LDU )
                   2739:                      CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),
                   2740:      $                            LDU )
                   2741:                      IE = ITAU
                   2742:                      ITAUQ = IE + M
                   2743:                      ITAUP = ITAUQ + M
                   2744:                      IWORK = ITAUP + M
                   2745: *
                   2746: *                    Bidiagonalize L in U
                   2747: *                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
                   2748: *
                   2749:                      CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),
                   2750:      $                            WORK( ITAUQ ), WORK( ITAUP ),
                   2751:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2752: *
                   2753: *                    Multiply right bidiagonalizing vectors in U by Q
                   2754: *                    in VT
                   2755: *                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
                   2756: *
                   2757:                      CALL DORMBR( 'P', 'L', 'T', M, N, M, U, LDU,
                   2758:      $                            WORK( ITAUP ), VT, LDVT,
                   2759:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2760: *
                   2761: *                    Generate left bidiagonalizing vectors in U
                   2762: *                    (Workspace: need 4*M, prefer 3*M+M*NB)
                   2763: *
                   2764:                      CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
                   2765:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2766:                      IWORK = IE + M
                   2767: *
                   2768: *                    Perform bidiagonal QR iteration, computing left
                   2769: *                    singular vectors of A in U and computing right
                   2770: *                    singular vectors of A in VT
                   2771: *                    (Workspace: need BDSPAC)
                   2772: *
                   2773:                      CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,
                   2774:      $                            LDVT, U, LDU, DUM, 1, WORK( IWORK ),
                   2775:      $                            INFO )
                   2776: *
                   2777:                   END IF
                   2778: *
                   2779:                END IF
                   2780: *
                   2781:             ELSE IF( WNTVA ) THEN
                   2782: *
                   2783:                IF( WNTUN ) THEN
                   2784: *
                   2785: *                 Path 7t(N much larger than M, JOBU='N', JOBVT='A')
                   2786: *                 N right singular vectors to be computed in VT and
                   2787: *                 no left singular vectors to be computed
                   2788: *
                   2789:                   IF( LWORK.GE.M*M+MAX( N+M, 4*M, BDSPAC ) ) THEN
                   2790: *
                   2791: *                    Sufficient workspace for a fast algorithm
                   2792: *
                   2793:                      IR = 1
                   2794:                      IF( LWORK.GE.WRKBL+LDA*M ) THEN
                   2795: *
                   2796: *                       WORK(IR) is LDA by M
                   2797: *
                   2798:                         LDWRKR = LDA
                   2799:                      ELSE
                   2800: *
                   2801: *                       WORK(IR) is M by M
                   2802: *
                   2803:                         LDWRKR = M
                   2804:                      END IF
                   2805:                      ITAU = IR + LDWRKR*M
                   2806:                      IWORK = ITAU + M
                   2807: *
                   2808: *                    Compute A=L*Q, copying result to VT
                   2809: *                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
                   2810: *
                   2811:                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
                   2812:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2813:                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
                   2814: *
                   2815: *                    Copy L to WORK(IR), zeroing out above it
                   2816: *
                   2817:                      CALL DLACPY( 'L', M, M, A, LDA, WORK( IR ),
                   2818:      $                            LDWRKR )
                   2819:                      CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
                   2820:      $                            WORK( IR+LDWRKR ), LDWRKR )
                   2821: *
                   2822: *                    Generate Q in VT
                   2823: *                    (Workspace: need M*M+M+N, prefer M*M+M+N*NB)
                   2824: *
                   2825:                      CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
                   2826:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2827:                      IE = ITAU
                   2828:                      ITAUQ = IE + M
                   2829:                      ITAUP = ITAUQ + M
                   2830:                      IWORK = ITAUP + M
                   2831: *
                   2832: *                    Bidiagonalize L in WORK(IR)
                   2833: *                    (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
                   2834: *
                   2835:                      CALL DGEBRD( M, M, WORK( IR ), LDWRKR, S,
                   2836:      $                            WORK( IE ), WORK( ITAUQ ),
                   2837:      $                            WORK( ITAUP ), WORK( IWORK ),
                   2838:      $                            LWORK-IWORK+1, IERR )
                   2839: *
                   2840: *                    Generate right bidiagonalizing vectors in WORK(IR)
                   2841: *                    (Workspace: need M*M+4*M-1,
                   2842: *                                prefer M*M+3*M+(M-1)*NB)
                   2843: *
                   2844:                      CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
                   2845:      $                            WORK( ITAUP ), WORK( IWORK ),
                   2846:      $                            LWORK-IWORK+1, IERR )
                   2847:                      IWORK = IE + M
                   2848: *
                   2849: *                    Perform bidiagonal QR iteration, computing right
                   2850: *                    singular vectors of L in WORK(IR)
                   2851: *                    (Workspace: need M*M+BDSPAC)
                   2852: *
                   2853:                      CALL DBDSQR( 'U', M, M, 0, 0, S, WORK( IE ),
                   2854:      $                            WORK( IR ), LDWRKR, DUM, 1, DUM, 1,
                   2855:      $                            WORK( IWORK ), INFO )
                   2856: *
                   2857: *                    Multiply right singular vectors of L in WORK(IR) by
                   2858: *                    Q in VT, storing result in A
                   2859: *                    (Workspace: need M*M)
                   2860: *
                   2861:                      CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IR ),
                   2862:      $                           LDWRKR, VT, LDVT, ZERO, A, LDA )
                   2863: *
                   2864: *                    Copy right singular vectors of A from A to VT
                   2865: *
                   2866:                      CALL DLACPY( 'F', M, N, A, LDA, VT, LDVT )
                   2867: *
                   2868:                   ELSE
                   2869: *
                   2870: *                    Insufficient workspace for a fast algorithm
                   2871: *
                   2872:                      ITAU = 1
                   2873:                      IWORK = ITAU + M
                   2874: *
                   2875: *                    Compute A=L*Q, copying result to VT
                   2876: *                    (Workspace: need 2*M, prefer M+M*NB)
                   2877: *
                   2878:                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
                   2879:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2880:                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
                   2881: *
                   2882: *                    Generate Q in VT
                   2883: *                    (Workspace: need M+N, prefer M+N*NB)
                   2884: *
                   2885:                      CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
                   2886:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2887:                      IE = ITAU
                   2888:                      ITAUQ = IE + M
                   2889:                      ITAUP = ITAUQ + M
                   2890:                      IWORK = ITAUP + M
                   2891: *
                   2892: *                    Zero out above L in A
                   2893: *
                   2894:                      CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),
                   2895:      $                            LDA )
                   2896: *
                   2897: *                    Bidiagonalize L in A
                   2898: *                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
                   2899: *
                   2900:                      CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),
                   2901:      $                            WORK( ITAUQ ), WORK( ITAUP ),
                   2902:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2903: *
                   2904: *                    Multiply right bidiagonalizing vectors in A by Q
                   2905: *                    in VT
                   2906: *                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
                   2907: *
                   2908:                      CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,
                   2909:      $                            WORK( ITAUP ), VT, LDVT,
                   2910:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2911:                      IWORK = IE + M
                   2912: *
                   2913: *                    Perform bidiagonal QR iteration, computing right
                   2914: *                    singular vectors of A in VT
                   2915: *                    (Workspace: need BDSPAC)
                   2916: *
                   2917:                      CALL DBDSQR( 'U', M, N, 0, 0, S, WORK( IE ), VT,
                   2918:      $                            LDVT, DUM, 1, DUM, 1, WORK( IWORK ),
                   2919:      $                            INFO )
                   2920: *
                   2921:                   END IF
                   2922: *
                   2923:                ELSE IF( WNTUO ) THEN
                   2924: *
                   2925: *                 Path 8t(N much larger than M, JOBU='O', JOBVT='A')
                   2926: *                 N right singular vectors to be computed in VT and
                   2927: *                 M left singular vectors to be overwritten on A
                   2928: *
                   2929:                   IF( LWORK.GE.2*M*M+MAX( N+M, 4*M, BDSPAC ) ) THEN
                   2930: *
                   2931: *                    Sufficient workspace for a fast algorithm
                   2932: *
                   2933:                      IU = 1
                   2934:                      IF( LWORK.GE.WRKBL+2*LDA*M ) THEN
                   2935: *
                   2936: *                       WORK(IU) is LDA by M and WORK(IR) is LDA by M
                   2937: *
                   2938:                         LDWRKU = LDA
                   2939:                         IR = IU + LDWRKU*M
                   2940:                         LDWRKR = LDA
                   2941:                      ELSE IF( LWORK.GE.WRKBL+( LDA+M )*M ) THEN
                   2942: *
                   2943: *                       WORK(IU) is LDA by M and WORK(IR) is M by M
                   2944: *
                   2945:                         LDWRKU = LDA
                   2946:                         IR = IU + LDWRKU*M
                   2947:                         LDWRKR = M
                   2948:                      ELSE
                   2949: *
                   2950: *                       WORK(IU) is M by M and WORK(IR) is M by M
                   2951: *
                   2952:                         LDWRKU = M
                   2953:                         IR = IU + LDWRKU*M
                   2954:                         LDWRKR = M
                   2955:                      END IF
                   2956:                      ITAU = IR + LDWRKR*M
                   2957:                      IWORK = ITAU + M
                   2958: *
                   2959: *                    Compute A=L*Q, copying result to VT
                   2960: *                    (Workspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)
                   2961: *
                   2962:                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
                   2963:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2964:                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
                   2965: *
                   2966: *                    Generate Q in VT
                   2967: *                    (Workspace: need 2*M*M+M+N, prefer 2*M*M+M+N*NB)
                   2968: *
                   2969:                      CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
                   2970:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   2971: *
                   2972: *                    Copy L to WORK(IU), zeroing out above it
                   2973: *
                   2974:                      CALL DLACPY( 'L', M, M, A, LDA, WORK( IU ),
                   2975:      $                            LDWRKU )
                   2976:                      CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
                   2977:      $                            WORK( IU+LDWRKU ), LDWRKU )
                   2978:                      IE = ITAU
                   2979:                      ITAUQ = IE + M
                   2980:                      ITAUP = ITAUQ + M
                   2981:                      IWORK = ITAUP + M
                   2982: *
                   2983: *                    Bidiagonalize L in WORK(IU), copying result to
                   2984: *                    WORK(IR)
                   2985: *                    (Workspace: need 2*M*M+4*M,
                   2986: *                                prefer 2*M*M+3*M+2*M*NB)
                   2987: *
                   2988:                      CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,
                   2989:      $                            WORK( IE ), WORK( ITAUQ ),
                   2990:      $                            WORK( ITAUP ), WORK( IWORK ),
                   2991:      $                            LWORK-IWORK+1, IERR )
                   2992:                      CALL DLACPY( 'L', M, M, WORK( IU ), LDWRKU,
                   2993:      $                            WORK( IR ), LDWRKR )
                   2994: *
                   2995: *                    Generate right bidiagonalizing vectors in WORK(IU)
                   2996: *                    (Workspace: need 2*M*M+4*M-1,
                   2997: *                                prefer 2*M*M+3*M+(M-1)*NB)
                   2998: *
                   2999:                      CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
                   3000:      $                            WORK( ITAUP ), WORK( IWORK ),
                   3001:      $                            LWORK-IWORK+1, IERR )
                   3002: *
                   3003: *                    Generate left bidiagonalizing vectors in WORK(IR)
                   3004: *                    (Workspace: need 2*M*M+4*M, prefer 2*M*M+3*M+M*NB)
                   3005: *
                   3006:                      CALL DORGBR( 'Q', M, M, M, WORK( IR ), LDWRKR,
                   3007:      $                            WORK( ITAUQ ), WORK( IWORK ),
                   3008:      $                            LWORK-IWORK+1, IERR )
                   3009:                      IWORK = IE + M
                   3010: *
                   3011: *                    Perform bidiagonal QR iteration, computing left
                   3012: *                    singular vectors of L in WORK(IR) and computing
                   3013: *                    right singular vectors of L in WORK(IU)
                   3014: *                    (Workspace: need 2*M*M+BDSPAC)
                   3015: *
                   3016:                      CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
                   3017:      $                            WORK( IU ), LDWRKU, WORK( IR ),
                   3018:      $                            LDWRKR, DUM, 1, WORK( IWORK ), INFO )
                   3019: *
                   3020: *                    Multiply right singular vectors of L in WORK(IU) by
                   3021: *                    Q in VT, storing result in A
                   3022: *                    (Workspace: need M*M)
                   3023: *
                   3024:                      CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),
                   3025:      $                           LDWRKU, VT, LDVT, ZERO, A, LDA )
                   3026: *
                   3027: *                    Copy right singular vectors of A from A to VT
                   3028: *
                   3029:                      CALL DLACPY( 'F', M, N, A, LDA, VT, LDVT )
                   3030: *
                   3031: *                    Copy left singular vectors of A from WORK(IR) to A
                   3032: *
                   3033:                      CALL DLACPY( 'F', M, M, WORK( IR ), LDWRKR, A,
                   3034:      $                            LDA )
                   3035: *
                   3036:                   ELSE
                   3037: *
                   3038: *                    Insufficient workspace for a fast algorithm
                   3039: *
                   3040:                      ITAU = 1
                   3041:                      IWORK = ITAU + M
                   3042: *
                   3043: *                    Compute A=L*Q, copying result to VT
                   3044: *                    (Workspace: need 2*M, prefer M+M*NB)
                   3045: *
                   3046:                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
                   3047:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   3048:                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
                   3049: *
                   3050: *                    Generate Q in VT
                   3051: *                    (Workspace: need M+N, prefer M+N*NB)
                   3052: *
                   3053:                      CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
                   3054:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   3055:                      IE = ITAU
                   3056:                      ITAUQ = IE + M
                   3057:                      ITAUP = ITAUQ + M
                   3058:                      IWORK = ITAUP + M
                   3059: *
                   3060: *                    Zero out above L in A
                   3061: *
                   3062:                      CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),
                   3063:      $                            LDA )
                   3064: *
                   3065: *                    Bidiagonalize L in A
                   3066: *                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
                   3067: *
                   3068:                      CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),
                   3069:      $                            WORK( ITAUQ ), WORK( ITAUP ),
                   3070:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   3071: *
                   3072: *                    Multiply right bidiagonalizing vectors in A by Q
                   3073: *                    in VT
                   3074: *                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
                   3075: *
                   3076:                      CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,
                   3077:      $                            WORK( ITAUP ), VT, LDVT,
                   3078:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   3079: *
                   3080: *                    Generate left bidiagonalizing vectors in A
                   3081: *                    (Workspace: need 4*M, prefer 3*M+M*NB)
                   3082: *
                   3083:                      CALL DORGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
                   3084:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   3085:                      IWORK = IE + M
                   3086: *
                   3087: *                    Perform bidiagonal QR iteration, computing left
                   3088: *                    singular vectors of A in A and computing right
                   3089: *                    singular vectors of A in VT
                   3090: *                    (Workspace: need BDSPAC)
                   3091: *
                   3092:                      CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,
                   3093:      $                            LDVT, A, LDA, DUM, 1, WORK( IWORK ),
                   3094:      $                            INFO )
                   3095: *
                   3096:                   END IF
                   3097: *
                   3098:                ELSE IF( WNTUAS ) THEN
                   3099: *
                   3100: *                 Path 9t(N much larger than M, JOBU='S' or 'A',
                   3101: *                         JOBVT='A')
                   3102: *                 N right singular vectors to be computed in VT and
                   3103: *                 M left singular vectors to be computed in U
                   3104: *
                   3105:                   IF( LWORK.GE.M*M+MAX( N+M, 4*M, BDSPAC ) ) THEN
                   3106: *
                   3107: *                    Sufficient workspace for a fast algorithm
                   3108: *
                   3109:                      IU = 1
                   3110:                      IF( LWORK.GE.WRKBL+LDA*M ) THEN
                   3111: *
                   3112: *                       WORK(IU) is LDA by M
                   3113: *
                   3114:                         LDWRKU = LDA
                   3115:                      ELSE
                   3116: *
                   3117: *                       WORK(IU) is M by M
                   3118: *
                   3119:                         LDWRKU = M
                   3120:                      END IF
                   3121:                      ITAU = IU + LDWRKU*M
                   3122:                      IWORK = ITAU + M
                   3123: *
                   3124: *                    Compute A=L*Q, copying result to VT
                   3125: *                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
                   3126: *
                   3127:                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
                   3128:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   3129:                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
                   3130: *
                   3131: *                    Generate Q in VT
                   3132: *                    (Workspace: need M*M+M+N, prefer M*M+M+N*NB)
                   3133: *
                   3134:                      CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
                   3135:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   3136: *
                   3137: *                    Copy L to WORK(IU), zeroing out above it
                   3138: *
                   3139:                      CALL DLACPY( 'L', M, M, A, LDA, WORK( IU ),
                   3140:      $                            LDWRKU )
                   3141:                      CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
                   3142:      $                            WORK( IU+LDWRKU ), LDWRKU )
                   3143:                      IE = ITAU
                   3144:                      ITAUQ = IE + M
                   3145:                      ITAUP = ITAUQ + M
                   3146:                      IWORK = ITAUP + M
                   3147: *
                   3148: *                    Bidiagonalize L in WORK(IU), copying result to U
                   3149: *                    (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
                   3150: *
                   3151:                      CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,
                   3152:      $                            WORK( IE ), WORK( ITAUQ ),
                   3153:      $                            WORK( ITAUP ), WORK( IWORK ),
                   3154:      $                            LWORK-IWORK+1, IERR )
                   3155:                      CALL DLACPY( 'L', M, M, WORK( IU ), LDWRKU, U,
                   3156:      $                            LDU )
                   3157: *
                   3158: *                    Generate right bidiagonalizing vectors in WORK(IU)
                   3159: *                    (Workspace: need M*M+4*M, prefer M*M+3*M+(M-1)*NB)
                   3160: *
                   3161:                      CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
                   3162:      $                            WORK( ITAUP ), WORK( IWORK ),
                   3163:      $                            LWORK-IWORK+1, IERR )
                   3164: *
                   3165: *                    Generate left bidiagonalizing vectors in U
                   3166: *                    (Workspace: need M*M+4*M, prefer M*M+3*M+M*NB)
                   3167: *
                   3168:                      CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
                   3169:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   3170:                      IWORK = IE + M
                   3171: *
                   3172: *                    Perform bidiagonal QR iteration, computing left
                   3173: *                    singular vectors of L in U and computing right
                   3174: *                    singular vectors of L in WORK(IU)
                   3175: *                    (Workspace: need M*M+BDSPAC)
                   3176: *
                   3177:                      CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
                   3178:      $                            WORK( IU ), LDWRKU, U, LDU, DUM, 1,
                   3179:      $                            WORK( IWORK ), INFO )
                   3180: *
                   3181: *                    Multiply right singular vectors of L in WORK(IU) by
                   3182: *                    Q in VT, storing result in A
                   3183: *                    (Workspace: need M*M)
                   3184: *
                   3185:                      CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),
                   3186:      $                           LDWRKU, VT, LDVT, ZERO, A, LDA )
                   3187: *
                   3188: *                    Copy right singular vectors of A from A to VT
                   3189: *
                   3190:                      CALL DLACPY( 'F', M, N, A, LDA, VT, LDVT )
                   3191: *
                   3192:                   ELSE
                   3193: *
                   3194: *                    Insufficient workspace for a fast algorithm
                   3195: *
                   3196:                      ITAU = 1
                   3197:                      IWORK = ITAU + M
                   3198: *
                   3199: *                    Compute A=L*Q, copying result to VT
                   3200: *                    (Workspace: need 2*M, prefer M+M*NB)
                   3201: *
                   3202:                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
                   3203:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   3204:                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
                   3205: *
                   3206: *                    Generate Q in VT
                   3207: *                    (Workspace: need M+N, prefer M+N*NB)
                   3208: *
                   3209:                      CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
                   3210:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   3211: *
                   3212: *                    Copy L to U, zeroing out above it
                   3213: *
                   3214:                      CALL DLACPY( 'L', M, M, A, LDA, U, LDU )
                   3215:                      CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),
                   3216:      $                            LDU )
                   3217:                      IE = ITAU
                   3218:                      ITAUQ = IE + M
                   3219:                      ITAUP = ITAUQ + M
                   3220:                      IWORK = ITAUP + M
                   3221: *
                   3222: *                    Bidiagonalize L in U
                   3223: *                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
                   3224: *
                   3225:                      CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),
                   3226:      $                            WORK( ITAUQ ), WORK( ITAUP ),
                   3227:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   3228: *
                   3229: *                    Multiply right bidiagonalizing vectors in U by Q
                   3230: *                    in VT
                   3231: *                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
                   3232: *
                   3233:                      CALL DORMBR( 'P', 'L', 'T', M, N, M, U, LDU,
                   3234:      $                            WORK( ITAUP ), VT, LDVT,
                   3235:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   3236: *
                   3237: *                    Generate left bidiagonalizing vectors in U
                   3238: *                    (Workspace: need 4*M, prefer 3*M+M*NB)
                   3239: *
                   3240:                      CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
                   3241:      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
                   3242:                      IWORK = IE + M
                   3243: *
                   3244: *                    Perform bidiagonal QR iteration, computing left
                   3245: *                    singular vectors of A in U and computing right
                   3246: *                    singular vectors of A in VT
                   3247: *                    (Workspace: need BDSPAC)
                   3248: *
                   3249:                      CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,
                   3250:      $                            LDVT, U, LDU, DUM, 1, WORK( IWORK ),
                   3251:      $                            INFO )
                   3252: *
                   3253:                   END IF
                   3254: *
                   3255:                END IF
                   3256: *
                   3257:             END IF
                   3258: *
                   3259:          ELSE
                   3260: *
                   3261: *           N .LT. MNTHR
                   3262: *
                   3263: *           Path 10t(N greater than M, but not much larger)
                   3264: *           Reduce to bidiagonal form without LQ decomposition
                   3265: *
                   3266:             IE = 1
                   3267:             ITAUQ = IE + M
                   3268:             ITAUP = ITAUQ + M
                   3269:             IWORK = ITAUP + M
                   3270: *
                   3271: *           Bidiagonalize A
                   3272: *           (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)
                   3273: *
                   3274:             CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
                   3275:      $                   WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
                   3276:      $                   IERR )
                   3277:             IF( WNTUAS ) THEN
                   3278: *
                   3279: *              If left singular vectors desired in U, copy result to U
                   3280: *              and generate left bidiagonalizing vectors in U
                   3281: *              (Workspace: need 4*M-1, prefer 3*M+(M-1)*NB)
                   3282: *
                   3283:                CALL DLACPY( 'L', M, M, A, LDA, U, LDU )
                   3284:                CALL DORGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
                   3285:      $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
                   3286:             END IF
                   3287:             IF( WNTVAS ) THEN
                   3288: *
                   3289: *              If right singular vectors desired in VT, copy result to
                   3290: *              VT and generate right bidiagonalizing vectors in VT
                   3291: *              (Workspace: need 3*M+NRVT, prefer 3*M+NRVT*NB)
                   3292: *
                   3293:                CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
                   3294:                IF( WNTVA )
                   3295:      $            NRVT = N
                   3296:                IF( WNTVS )
                   3297:      $            NRVT = M
                   3298:                CALL DORGBR( 'P', NRVT, N, M, VT, LDVT, WORK( ITAUP ),
                   3299:      $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
                   3300:             END IF
                   3301:             IF( WNTUO ) THEN
                   3302: *
                   3303: *              If left singular vectors desired in A, generate left
                   3304: *              bidiagonalizing vectors in A
                   3305: *              (Workspace: need 4*M-1, prefer 3*M+(M-1)*NB)
                   3306: *
                   3307:                CALL DORGBR( 'Q', M, M, N, A, LDA, WORK( ITAUQ ),
                   3308:      $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
                   3309:             END IF
                   3310:             IF( WNTVO ) THEN
                   3311: *
                   3312: *              If right singular vectors desired in A, generate right
                   3313: *              bidiagonalizing vectors in A
                   3314: *              (Workspace: need 4*M, prefer 3*M+M*NB)
                   3315: *
                   3316:                CALL DORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
                   3317:      $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
                   3318:             END IF
                   3319:             IWORK = IE + M
                   3320:             IF( WNTUAS .OR. WNTUO )
                   3321:      $         NRU = M
                   3322:             IF( WNTUN )
                   3323:      $         NRU = 0
                   3324:             IF( WNTVAS .OR. WNTVO )
                   3325:      $         NCVT = N
                   3326:             IF( WNTVN )
                   3327:      $         NCVT = 0
                   3328:             IF( ( .NOT.WNTUO ) .AND. ( .NOT.WNTVO ) ) THEN
                   3329: *
                   3330: *              Perform bidiagonal QR iteration, if desired, computing
                   3331: *              left singular vectors in U and computing right singular
                   3332: *              vectors in VT
                   3333: *              (Workspace: need BDSPAC)
                   3334: *
                   3335:                CALL DBDSQR( 'L', M, NCVT, NRU, 0, S, WORK( IE ), VT,
                   3336:      $                      LDVT, U, LDU, DUM, 1, WORK( IWORK ), INFO )
                   3337:             ELSE IF( ( .NOT.WNTUO ) .AND. WNTVO ) THEN
                   3338: *
                   3339: *              Perform bidiagonal QR iteration, if desired, computing
                   3340: *              left singular vectors in U and computing right singular
                   3341: *              vectors in A
                   3342: *              (Workspace: need BDSPAC)
                   3343: *
                   3344:                CALL DBDSQR( 'L', M, NCVT, NRU, 0, S, WORK( IE ), A, LDA,
                   3345:      $                      U, LDU, DUM, 1, WORK( IWORK ), INFO )
                   3346:             ELSE
                   3347: *
                   3348: *              Perform bidiagonal QR iteration, if desired, computing
                   3349: *              left singular vectors in A and computing right singular
                   3350: *              vectors in VT
                   3351: *              (Workspace: need BDSPAC)
                   3352: *
                   3353:                CALL DBDSQR( 'L', M, NCVT, NRU, 0, S, WORK( IE ), VT,
                   3354:      $                      LDVT, A, LDA, DUM, 1, WORK( IWORK ), INFO )
                   3355:             END IF
                   3356: *
                   3357:          END IF
                   3358: *
                   3359:       END IF
                   3360: *
                   3361: *     If DBDSQR failed to converge, copy unconverged superdiagonals
                   3362: *     to WORK( 2:MINMN )
                   3363: *
                   3364:       IF( INFO.NE.0 ) THEN
                   3365:          IF( IE.GT.2 ) THEN
                   3366:             DO 50 I = 1, MINMN - 1
                   3367:                WORK( I+1 ) = WORK( I+IE-1 )
                   3368:    50       CONTINUE
                   3369:          END IF
                   3370:          IF( IE.LT.2 ) THEN
                   3371:             DO 60 I = MINMN - 1, 1, -1
                   3372:                WORK( I+1 ) = WORK( I+IE-1 )
                   3373:    60       CONTINUE
                   3374:          END IF
                   3375:       END IF
                   3376: *
                   3377: *     Undo scaling if necessary
                   3378: *
                   3379:       IF( ISCL.EQ.1 ) THEN
                   3380:          IF( ANRM.GT.BIGNUM )
                   3381:      $      CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,
                   3382:      $                   IERR )
                   3383:          IF( INFO.NE.0 .AND. ANRM.GT.BIGNUM )
                   3384:      $      CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN-1, 1, WORK( 2 ),
                   3385:      $                   MINMN, IERR )
                   3386:          IF( ANRM.LT.SMLNUM )
                   3387:      $      CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,
                   3388:      $                   IERR )
                   3389:          IF( INFO.NE.0 .AND. ANRM.LT.SMLNUM )
                   3390:      $      CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN-1, 1, WORK( 2 ),
                   3391:      $                   MINMN, IERR )
                   3392:       END IF
                   3393: *
                   3394: *     Return optimal workspace in WORK(1)
                   3395: *
                   3396:       WORK( 1 ) = MAXWRK
                   3397: *
                   3398:       RETURN
                   3399: *
                   3400: *     End of DGESVD
                   3401: *
                   3402:       END

CVSweb interface <joel.bertrand@systella.fr>