Annotation of rpl/lapack/lapack/zgesvd.f, revision 1.20

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

CVSweb interface <joel.bertrand@systella.fr>