Annotation of rpl/lapack/lapack/zgesdd.f, revision 1.3

1.1       bertrand    1:       SUBROUTINE ZGESDD( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT, WORK,
                      2:      $                   LWORK, RWORK, IWORK, INFO )
                      3: *
                      4: *  -- LAPACK driver routine (version 3.2) --
                      5: *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
                      6: *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
                      7: *     November 2006
                      8: *     8-15-00:  Improve consistency of WS calculations (eca)
                      9: *
                     10: *     .. Scalar Arguments ..
                     11:       CHARACTER          JOBZ
                     12:       INTEGER            INFO, LDA, LDU, LDVT, LWORK, M, N
                     13: *     ..
                     14: *     .. Array Arguments ..
                     15:       INTEGER            IWORK( * )
                     16:       DOUBLE PRECISION   RWORK( * ), S( * )
                     17:       COMPLEX*16         A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
                     18:      $                   WORK( * )
                     19: *     ..
                     20: *
                     21: *  Purpose
                     22: *  =======
                     23: *
                     24: *  ZGESDD computes the singular value decomposition (SVD) of a complex
                     25: *  M-by-N matrix A, optionally computing the left and/or right singular
                     26: *  vectors, by using divide-and-conquer method. The SVD is written
                     27: *
                     28: *       A = U * SIGMA * conjugate-transpose(V)
                     29: *
                     30: *  where SIGMA is an M-by-N matrix which is zero except for its
                     31: *  min(m,n) diagonal elements, U is an M-by-M unitary matrix, and
                     32: *  V is an N-by-N unitary matrix.  The diagonal elements of SIGMA
                     33: *  are the singular values of A; they are real and non-negative, and
                     34: *  are returned in descending order.  The first min(m,n) columns of
                     35: *  U and V are the left and right singular vectors of A.
                     36: *
                     37: *  Note that the routine returns VT = V**H, not V.
                     38: *
                     39: *  The divide and conquer algorithm makes very mild assumptions about
                     40: *  floating point arithmetic. It will work on machines with a guard
                     41: *  digit in add/subtract, or on those binary machines without guard
                     42: *  digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or
                     43: *  Cray-2. It could conceivably fail on hexadecimal or decimal machines
                     44: *  without guard digits, but we know of none.
                     45: *
                     46: *  Arguments
                     47: *  =========
                     48: *
                     49: *  JOBZ    (input) CHARACTER*1
                     50: *          Specifies options for computing all or part of the matrix U:
                     51: *          = 'A':  all M columns of U and all N rows of V**H are
                     52: *                  returned in the arrays U and VT;
                     53: *          = 'S':  the first min(M,N) columns of U and the first
                     54: *                  min(M,N) rows of V**H are returned in the arrays U
                     55: *                  and VT;
                     56: *          = 'O':  If M >= N, the first N columns of U are overwritten
                     57: *                  in the array A and all rows of V**H are returned in
                     58: *                  the array VT;
                     59: *                  otherwise, all columns of U are returned in the
                     60: *                  array U and the first M rows of V**H are overwritten
                     61: *                  in the array A;
                     62: *          = 'N':  no columns of U or rows of V**H are computed.
                     63: *
                     64: *  M       (input) INTEGER
                     65: *          The number of rows of the input matrix A.  M >= 0.
                     66: *
                     67: *  N       (input) INTEGER
                     68: *          The number of columns of the input matrix A.  N >= 0.
                     69: *
                     70: *  A       (input/output) COMPLEX*16 array, dimension (LDA,N)
                     71: *          On entry, the M-by-N matrix A.
                     72: *          On exit,
                     73: *          if JOBZ = 'O',  A is overwritten with the first N columns
                     74: *                          of U (the left singular vectors, stored
                     75: *                          columnwise) if M >= N;
                     76: *                          A is overwritten with the first M rows
                     77: *                          of V**H (the right singular vectors, stored
                     78: *                          rowwise) otherwise.
                     79: *          if JOBZ .ne. 'O', the contents of A are destroyed.
                     80: *
                     81: *  LDA     (input) INTEGER
                     82: *          The leading dimension of the array A.  LDA >= max(1,M).
                     83: *
                     84: *  S       (output) DOUBLE PRECISION array, dimension (min(M,N))
                     85: *          The singular values of A, sorted so that S(i) >= S(i+1).
                     86: *
                     87: *  U       (output) COMPLEX*16 array, dimension (LDU,UCOL)
                     88: *          UCOL = M if JOBZ = 'A' or JOBZ = 'O' and M < N;
                     89: *          UCOL = min(M,N) if JOBZ = 'S'.
                     90: *          If JOBZ = 'A' or JOBZ = 'O' and M < N, U contains the M-by-M
                     91: *          unitary matrix U;
                     92: *          if JOBZ = 'S', U contains the first min(M,N) columns of U
                     93: *          (the left singular vectors, stored columnwise);
                     94: *          if JOBZ = 'O' and M >= N, or JOBZ = 'N', U is not referenced.
                     95: *
                     96: *  LDU     (input) INTEGER
                     97: *          The leading dimension of the array U.  LDU >= 1; if
                     98: *          JOBZ = 'S' or 'A' or JOBZ = 'O' and M < N, LDU >= M.
                     99: *
                    100: *  VT      (output) COMPLEX*16 array, dimension (LDVT,N)
                    101: *          If JOBZ = 'A' or JOBZ = 'O' and M >= N, VT contains the
                    102: *          N-by-N unitary matrix V**H;
                    103: *          if JOBZ = 'S', VT contains the first min(M,N) rows of
                    104: *          V**H (the right singular vectors, stored rowwise);
                    105: *          if JOBZ = 'O' and M < N, or JOBZ = 'N', VT is not referenced.
                    106: *
                    107: *  LDVT    (input) INTEGER
                    108: *          The leading dimension of the array VT.  LDVT >= 1; if
                    109: *          JOBZ = 'A' or JOBZ = 'O' and M >= N, LDVT >= N;
                    110: *          if JOBZ = 'S', LDVT >= min(M,N).
                    111: *
                    112: *  WORK    (workspace/output) COMPLEX*16 array, dimension (MAX(1,LWORK))
                    113: *          On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
                    114: *
                    115: *  LWORK   (input) INTEGER
                    116: *          The dimension of the array WORK. LWORK >= 1.
                    117: *          if JOBZ = 'N', LWORK >= 2*min(M,N)+max(M,N).
                    118: *          if JOBZ = 'O',
                    119: *                LWORK >= 2*min(M,N)*min(M,N)+2*min(M,N)+max(M,N).
                    120: *          if JOBZ = 'S' or 'A',
                    121: *                LWORK >= min(M,N)*min(M,N)+2*min(M,N)+max(M,N).
                    122: *          For good performance, LWORK should generally be larger.
                    123: *
                    124: *          If LWORK = -1, a workspace query is assumed.  The optimal
                    125: *          size for the WORK array is calculated and stored in WORK(1),
                    126: *          and no other work except argument checking is performed.
                    127: *
                    128: *  RWORK   (workspace) DOUBLE PRECISION array, dimension (MAX(1,LRWORK))
                    129: *          If JOBZ = 'N', LRWORK >= 5*min(M,N).
                    130: *          Otherwise, LRWORK >= 5*min(M,N)*min(M,N) + 7*min(M,N)
                    131: *
                    132: *  IWORK   (workspace) INTEGER array, dimension (8*min(M,N))
                    133: *
                    134: *  INFO    (output) INTEGER
                    135: *          = 0:  successful exit.
                    136: *          < 0:  if INFO = -i, the i-th argument had an illegal value.
                    137: *          > 0:  The updating process of DBDSDC did not converge.
                    138: *
                    139: *  Further Details
                    140: *  ===============
                    141: *
                    142: *  Based on contributions by
                    143: *     Ming Gu and Huan Ren, Computer Science Division, University of
                    144: *     California at Berkeley, USA
                    145: *
                    146: *  =====================================================================
                    147: *
                    148: *     .. Parameters ..
                    149:       INTEGER            LQUERV
                    150:       PARAMETER          ( LQUERV = -1 )
                    151:       COMPLEX*16         CZERO, CONE
                    152:       PARAMETER          ( CZERO = ( 0.0D+0, 0.0D+0 ),
                    153:      $                   CONE = ( 1.0D+0, 0.0D+0 ) )
                    154:       DOUBLE PRECISION   ZERO, ONE
                    155:       PARAMETER          ( ZERO = 0.0D+0, ONE = 1.0D+0 )
                    156: *     ..
                    157: *     .. Local Scalars ..
                    158:       LOGICAL            WNTQA, WNTQAS, WNTQN, WNTQO, WNTQS
                    159:       INTEGER            BLK, CHUNK, I, IE, IERR, IL, IR, IRU, IRVT,
                    160:      $                   ISCL, ITAU, ITAUP, ITAUQ, IU, IVT, LDWKVT,
                    161:      $                   LDWRKL, LDWRKR, LDWRKU, MAXWRK, MINMN, MINWRK,
                    162:      $                   MNTHR1, MNTHR2, NRWORK, NWORK, WRKBL
                    163:       DOUBLE PRECISION   ANRM, BIGNUM, EPS, SMLNUM
                    164: *     ..
                    165: *     .. Local Arrays ..
                    166:       INTEGER            IDUM( 1 )
                    167:       DOUBLE PRECISION   DUM( 1 )
                    168: *     ..
                    169: *     .. External Subroutines ..
                    170:       EXTERNAL           DBDSDC, DLASCL, XERBLA, ZGEBRD, ZGELQF, ZGEMM,
                    171:      $                   ZGEQRF, ZLACP2, ZLACPY, ZLACRM, ZLARCM, ZLASCL,
                    172:      $                   ZLASET, ZUNGBR, ZUNGLQ, ZUNGQR, ZUNMBR
                    173: *     ..
                    174: *     .. External Functions ..
                    175:       LOGICAL            LSAME
                    176:       INTEGER            ILAENV
                    177:       DOUBLE PRECISION   DLAMCH, ZLANGE
                    178:       EXTERNAL           LSAME, ILAENV, DLAMCH, ZLANGE
                    179: *     ..
                    180: *     .. Intrinsic Functions ..
                    181:       INTRINSIC          INT, MAX, MIN, SQRT
                    182: *     ..
                    183: *     .. Executable Statements ..
                    184: *
                    185: *     Test the input arguments
                    186: *
                    187:       INFO = 0
                    188:       MINMN = MIN( M, N )
                    189:       MNTHR1 = INT( MINMN*17.0D0 / 9.0D0 )
                    190:       MNTHR2 = INT( MINMN*5.0D0 / 3.0D0 )
                    191:       WNTQA = LSAME( JOBZ, 'A' )
                    192:       WNTQS = LSAME( JOBZ, 'S' )
                    193:       WNTQAS = WNTQA .OR. WNTQS
                    194:       WNTQO = LSAME( JOBZ, 'O' )
                    195:       WNTQN = LSAME( JOBZ, 'N' )
                    196:       MINWRK = 1
                    197:       MAXWRK = 1
                    198: *
                    199:       IF( .NOT.( WNTQA .OR. WNTQS .OR. WNTQO .OR. WNTQN ) ) THEN
                    200:          INFO = -1
                    201:       ELSE IF( M.LT.0 ) THEN
                    202:          INFO = -2
                    203:       ELSE IF( N.LT.0 ) THEN
                    204:          INFO = -3
                    205:       ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
                    206:          INFO = -5
                    207:       ELSE IF( LDU.LT.1 .OR. ( WNTQAS .AND. LDU.LT.M ) .OR.
                    208:      $         ( WNTQO .AND. M.LT.N .AND. LDU.LT.M ) ) THEN
                    209:          INFO = -8
                    210:       ELSE IF( LDVT.LT.1 .OR. ( WNTQA .AND. LDVT.LT.N ) .OR.
                    211:      $         ( WNTQS .AND. LDVT.LT.MINMN ) .OR.
                    212:      $         ( WNTQO .AND. M.GE.N .AND. LDVT.LT.N ) ) THEN
                    213:          INFO = -10
                    214:       END IF
                    215: *
                    216: *     Compute workspace
                    217: *      (Note: Comments in the code beginning "Workspace:" describe the
                    218: *       minimal amount of workspace needed at that point in the code,
                    219: *       as well as the preferred amount for good performance.
                    220: *       CWorkspace refers to complex workspace, and RWorkspace to
                    221: *       real workspace. NB refers to the optimal block size for the
                    222: *       immediately following subroutine, as returned by ILAENV.)
                    223: *
                    224:       IF( INFO.EQ.0 .AND. M.GT.0 .AND. N.GT.0 ) THEN
                    225:          IF( M.GE.N ) THEN
                    226: *
                    227: *           There is no complex work space needed for bidiagonal SVD
                    228: *           The real work space needed for bidiagonal SVD is BDSPAC
                    229: *           for computing singular values and singular vectors; BDSPAN
                    230: *           for computing singular values only.
                    231: *           BDSPAC = 5*N*N + 7*N
                    232: *           BDSPAN = MAX(7*N+4, 3*N+2+SMLSIZ*(SMLSIZ+8))
                    233: *
                    234:             IF( M.GE.MNTHR1 ) THEN
                    235:                IF( WNTQN ) THEN
                    236: *
                    237: *                 Path 1 (M much larger than N, JOBZ='N')
                    238: *
                    239:                   MAXWRK = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1,
                    240:      $                     -1 )
                    241:                   MAXWRK = MAX( MAXWRK, 2*N+2*N*
                    242:      $                     ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
                    243:                   MINWRK = 3*N
                    244:                ELSE IF( WNTQO ) THEN
                    245: *
                    246: *                 Path 2 (M much larger than N, JOBZ='O')
                    247: *
                    248:                   WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
                    249:                   WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'ZUNGQR', ' ', M,
                    250:      $                    N, N, -1 ) )
                    251:                   WRKBL = MAX( WRKBL, 2*N+2*N*
                    252:      $                    ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
                    253:                   WRKBL = MAX( WRKBL, 2*N+N*
                    254:      $                    ILAENV( 1, 'ZUNMBR', 'QLN', N, N, N, -1 ) )
                    255:                   WRKBL = MAX( WRKBL, 2*N+N*
                    256:      $                    ILAENV( 1, 'ZUNMBR', 'PRC', N, N, N, -1 ) )
                    257:                   MAXWRK = M*N + N*N + WRKBL
                    258:                   MINWRK = 2*N*N + 3*N
                    259:                ELSE IF( WNTQS ) THEN
                    260: *
                    261: *                 Path 3 (M much larger than N, JOBZ='S')
                    262: *
                    263:                   WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
                    264:                   WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'ZUNGQR', ' ', M,
                    265:      $                    N, N, -1 ) )
                    266:                   WRKBL = MAX( WRKBL, 2*N+2*N*
                    267:      $                    ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
                    268:                   WRKBL = MAX( WRKBL, 2*N+N*
                    269:      $                    ILAENV( 1, 'ZUNMBR', 'QLN', N, N, N, -1 ) )
                    270:                   WRKBL = MAX( WRKBL, 2*N+N*
                    271:      $                    ILAENV( 1, 'ZUNMBR', 'PRC', N, N, N, -1 ) )
                    272:                   MAXWRK = N*N + WRKBL
                    273:                   MINWRK = N*N + 3*N
                    274:                ELSE IF( WNTQA ) THEN
                    275: *
                    276: *                 Path 4 (M much larger than N, JOBZ='A')
                    277: *
                    278:                   WRKBL = N + N*ILAENV( 1, 'ZGEQRF', ' ', M, N, -1, -1 )
                    279:                   WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'ZUNGQR', ' ', M,
                    280:      $                    M, N, -1 ) )
                    281:                   WRKBL = MAX( WRKBL, 2*N+2*N*
                    282:      $                    ILAENV( 1, 'ZGEBRD', ' ', N, N, -1, -1 ) )
                    283:                   WRKBL = MAX( WRKBL, 2*N+N*
                    284:      $                    ILAENV( 1, 'ZUNMBR', 'QLN', N, N, N, -1 ) )
                    285:                   WRKBL = MAX( WRKBL, 2*N+N*
                    286:      $                    ILAENV( 1, 'ZUNMBR', 'PRC', N, N, N, -1 ) )
                    287:                   MAXWRK = N*N + WRKBL
                    288:                   MINWRK = N*N + 2*N + M
                    289:                END IF
                    290:             ELSE IF( M.GE.MNTHR2 ) THEN
                    291: *
                    292: *              Path 5 (M much larger than N, but not as much as MNTHR1)
                    293: *
                    294:                MAXWRK = 2*N + ( M+N )*ILAENV( 1, 'ZGEBRD', ' ', M, N,
                    295:      $                  -1, -1 )
                    296:                MINWRK = 2*N + M
                    297:                IF( WNTQO ) THEN
                    298:                   MAXWRK = MAX( MAXWRK, 2*N+N*
                    299:      $                     ILAENV( 1, 'ZUNGBR', 'P', N, N, N, -1 ) )
                    300:                   MAXWRK = MAX( MAXWRK, 2*N+N*
                    301:      $                     ILAENV( 1, 'ZUNGBR', 'Q', M, N, N, -1 ) )
                    302:                   MAXWRK = MAXWRK + M*N
                    303:                   MINWRK = MINWRK + N*N
                    304:                ELSE IF( WNTQS ) THEN
                    305:                   MAXWRK = MAX( MAXWRK, 2*N+N*
                    306:      $                     ILAENV( 1, 'ZUNGBR', 'P', N, N, N, -1 ) )
                    307:                   MAXWRK = MAX( MAXWRK, 2*N+N*
                    308:      $                     ILAENV( 1, 'ZUNGBR', 'Q', M, N, N, -1 ) )
                    309:                ELSE IF( WNTQA ) THEN
                    310:                   MAXWRK = MAX( MAXWRK, 2*N+N*
                    311:      $                     ILAENV( 1, 'ZUNGBR', 'P', N, N, N, -1 ) )
                    312:                   MAXWRK = MAX( MAXWRK, 2*N+M*
                    313:      $                     ILAENV( 1, 'ZUNGBR', 'Q', M, M, N, -1 ) )
                    314:                END IF
                    315:             ELSE
                    316: *
                    317: *              Path 6 (M at least N, but not much larger)
                    318: *
                    319:                MAXWRK = 2*N + ( M+N )*ILAENV( 1, 'ZGEBRD', ' ', M, N,
                    320:      $                  -1, -1 )
                    321:                MINWRK = 2*N + M
                    322:                IF( WNTQO ) THEN
                    323:                   MAXWRK = MAX( MAXWRK, 2*N+N*
                    324:      $                     ILAENV( 1, 'ZUNMBR', 'PRC', N, N, N, -1 ) )
                    325:                   MAXWRK = MAX( MAXWRK, 2*N+N*
                    326:      $                     ILAENV( 1, 'ZUNMBR', 'QLN', M, N, N, -1 ) )
                    327:                   MAXWRK = MAXWRK + M*N
                    328:                   MINWRK = MINWRK + N*N
                    329:                ELSE IF( WNTQS ) THEN
                    330:                   MAXWRK = MAX( MAXWRK, 2*N+N*
                    331:      $                     ILAENV( 1, 'ZUNMBR', 'PRC', N, N, N, -1 ) )
                    332:                   MAXWRK = MAX( MAXWRK, 2*N+N*
                    333:      $                     ILAENV( 1, 'ZUNMBR', 'QLN', M, N, N, -1 ) )
                    334:                ELSE IF( WNTQA ) THEN
                    335:                   MAXWRK = MAX( MAXWRK, 2*N+N*
                    336:      $                     ILAENV( 1, 'ZUNGBR', 'PRC', N, N, N, -1 ) )
                    337:                   MAXWRK = MAX( MAXWRK, 2*N+M*
                    338:      $                     ILAENV( 1, 'ZUNGBR', 'QLN', M, M, N, -1 ) )
                    339:                END IF
                    340:             END IF
                    341:          ELSE
                    342: *
                    343: *           There is no complex work space needed for bidiagonal SVD
                    344: *           The real work space needed for bidiagonal SVD is BDSPAC
                    345: *           for computing singular values and singular vectors; BDSPAN
                    346: *           for computing singular values only.
                    347: *           BDSPAC = 5*M*M + 7*M
                    348: *           BDSPAN = MAX(7*M+4, 3*M+2+SMLSIZ*(SMLSIZ+8))
                    349: *
                    350:             IF( N.GE.MNTHR1 ) THEN
                    351:                IF( WNTQN ) THEN
                    352: *
                    353: *                 Path 1t (N much larger than M, JOBZ='N')
                    354: *
                    355:                   MAXWRK = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1,
                    356:      $                     -1 )
                    357:                   MAXWRK = MAX( MAXWRK, 2*M+2*M*
                    358:      $                     ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
                    359:                   MINWRK = 3*M
                    360:                ELSE IF( WNTQO ) THEN
                    361: *
                    362: *                 Path 2t (N much larger than M, JOBZ='O')
                    363: *
                    364:                   WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
                    365:                   WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'ZUNGLQ', ' ', M,
                    366:      $                    N, M, -1 ) )
                    367:                   WRKBL = MAX( WRKBL, 2*M+2*M*
                    368:      $                    ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
                    369:                   WRKBL = MAX( WRKBL, 2*M+M*
                    370:      $                    ILAENV( 1, 'ZUNMBR', 'PRC', M, M, M, -1 ) )
                    371:                   WRKBL = MAX( WRKBL, 2*M+M*
                    372:      $                    ILAENV( 1, 'ZUNMBR', 'QLN', M, M, M, -1 ) )
                    373:                   MAXWRK = M*N + M*M + WRKBL
                    374:                   MINWRK = 2*M*M + 3*M
                    375:                ELSE IF( WNTQS ) THEN
                    376: *
                    377: *                 Path 3t (N much larger than M, JOBZ='S')
                    378: *
                    379:                   WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
                    380:                   WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'ZUNGLQ', ' ', M,
                    381:      $                    N, M, -1 ) )
                    382:                   WRKBL = MAX( WRKBL, 2*M+2*M*
                    383:      $                    ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
                    384:                   WRKBL = MAX( WRKBL, 2*M+M*
                    385:      $                    ILAENV( 1, 'ZUNMBR', 'PRC', M, M, M, -1 ) )
                    386:                   WRKBL = MAX( WRKBL, 2*M+M*
                    387:      $                    ILAENV( 1, 'ZUNMBR', 'QLN', M, M, M, -1 ) )
                    388:                   MAXWRK = M*M + WRKBL
                    389:                   MINWRK = M*M + 3*M
                    390:                ELSE IF( WNTQA ) THEN
                    391: *
                    392: *                 Path 4t (N much larger than M, JOBZ='A')
                    393: *
                    394:                   WRKBL = M + M*ILAENV( 1, 'ZGELQF', ' ', M, N, -1, -1 )
                    395:                   WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'ZUNGLQ', ' ', N,
                    396:      $                    N, M, -1 ) )
                    397:                   WRKBL = MAX( WRKBL, 2*M+2*M*
                    398:      $                    ILAENV( 1, 'ZGEBRD', ' ', M, M, -1, -1 ) )
                    399:                   WRKBL = MAX( WRKBL, 2*M+M*
                    400:      $                    ILAENV( 1, 'ZUNMBR', 'PRC', M, M, M, -1 ) )
                    401:                   WRKBL = MAX( WRKBL, 2*M+M*
                    402:      $                    ILAENV( 1, 'ZUNMBR', 'QLN', M, M, M, -1 ) )
                    403:                   MAXWRK = M*M + WRKBL
                    404:                   MINWRK = M*M + 2*M + N
                    405:                END IF
                    406:             ELSE IF( N.GE.MNTHR2 ) THEN
                    407: *
                    408: *              Path 5t (N much larger than M, but not as much as MNTHR1)
                    409: *
                    410:                MAXWRK = 2*M + ( M+N )*ILAENV( 1, 'ZGEBRD', ' ', M, N,
                    411:      $                  -1, -1 )
                    412:                MINWRK = 2*M + N
                    413:                IF( WNTQO ) THEN
                    414:                   MAXWRK = MAX( MAXWRK, 2*M+M*
                    415:      $                     ILAENV( 1, 'ZUNGBR', 'P', M, N, M, -1 ) )
                    416:                   MAXWRK = MAX( MAXWRK, 2*M+M*
                    417:      $                     ILAENV( 1, 'ZUNGBR', 'Q', M, M, N, -1 ) )
                    418:                   MAXWRK = MAXWRK + M*N
                    419:                   MINWRK = MINWRK + M*M
                    420:                ELSE IF( WNTQS ) THEN
                    421:                   MAXWRK = MAX( MAXWRK, 2*M+M*
                    422:      $                     ILAENV( 1, 'ZUNGBR', 'P', M, N, M, -1 ) )
                    423:                   MAXWRK = MAX( MAXWRK, 2*M+M*
                    424:      $                     ILAENV( 1, 'ZUNGBR', 'Q', M, M, N, -1 ) )
                    425:                ELSE IF( WNTQA ) THEN
                    426:                   MAXWRK = MAX( MAXWRK, 2*M+N*
                    427:      $                     ILAENV( 1, 'ZUNGBR', 'P', N, N, M, -1 ) )
                    428:                   MAXWRK = MAX( MAXWRK, 2*M+M*
                    429:      $                     ILAENV( 1, 'ZUNGBR', 'Q', M, M, N, -1 ) )
                    430:                END IF
                    431:             ELSE
                    432: *
                    433: *              Path 6t (N greater than M, but not much larger)
                    434: *
                    435:                MAXWRK = 2*M + ( M+N )*ILAENV( 1, 'ZGEBRD', ' ', M, N,
                    436:      $                  -1, -1 )
                    437:                MINWRK = 2*M + N
                    438:                IF( WNTQO ) THEN
                    439:                   MAXWRK = MAX( MAXWRK, 2*M+M*
                    440:      $                     ILAENV( 1, 'ZUNMBR', 'PRC', M, N, M, -1 ) )
                    441:                   MAXWRK = MAX( MAXWRK, 2*M+M*
                    442:      $                     ILAENV( 1, 'ZUNMBR', 'QLN', M, M, N, -1 ) )
                    443:                   MAXWRK = MAXWRK + M*N
                    444:                   MINWRK = MINWRK + M*M
                    445:                ELSE IF( WNTQS ) THEN
                    446:                   MAXWRK = MAX( MAXWRK, 2*M+M*
                    447:      $                     ILAENV( 1, 'ZUNGBR', 'PRC', M, N, M, -1 ) )
                    448:                   MAXWRK = MAX( MAXWRK, 2*M+M*
                    449:      $                     ILAENV( 1, 'ZUNGBR', 'QLN', M, M, N, -1 ) )
                    450:                ELSE IF( WNTQA ) THEN
                    451:                   MAXWRK = MAX( MAXWRK, 2*M+N*
                    452:      $                     ILAENV( 1, 'ZUNGBR', 'PRC', N, N, M, -1 ) )
                    453:                   MAXWRK = MAX( MAXWRK, 2*M+M*
                    454:      $                     ILAENV( 1, 'ZUNGBR', 'QLN', M, M, N, -1 ) )
                    455:                END IF
                    456:             END IF
                    457:          END IF
                    458:          MAXWRK = MAX( MAXWRK, MINWRK )
                    459:       END IF
                    460:       IF( INFO.EQ.0 ) THEN
                    461:          WORK( 1 ) = MAXWRK
                    462:          IF( LWORK.LT.MINWRK .AND. LWORK.NE.LQUERV )
                    463:      $      INFO = -13
                    464:       END IF
                    465: *
                    466: *     Quick returns
                    467: *
                    468:       IF( INFO.NE.0 ) THEN
                    469:          CALL XERBLA( 'ZGESDD', -INFO )
                    470:          RETURN
                    471:       END IF
                    472:       IF( LWORK.EQ.LQUERV )
                    473:      $   RETURN
                    474:       IF( M.EQ.0 .OR. N.EQ.0 ) THEN
                    475:          RETURN
                    476:       END IF
                    477: *
                    478: *     Get machine constants
                    479: *
                    480:       EPS = DLAMCH( 'P' )
                    481:       SMLNUM = SQRT( DLAMCH( 'S' ) ) / EPS
                    482:       BIGNUM = ONE / SMLNUM
                    483: *
                    484: *     Scale A if max element outside range [SMLNUM,BIGNUM]
                    485: *
                    486:       ANRM = ZLANGE( 'M', M, N, A, LDA, DUM )
                    487:       ISCL = 0
                    488:       IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
                    489:          ISCL = 1
                    490:          CALL ZLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, IERR )
                    491:       ELSE IF( ANRM.GT.BIGNUM ) THEN
                    492:          ISCL = 1
                    493:          CALL ZLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, IERR )
                    494:       END IF
                    495: *
                    496:       IF( M.GE.N ) THEN
                    497: *
                    498: *        A has at least as many rows as columns. If A has sufficiently
                    499: *        more rows than columns, first reduce using the QR
                    500: *        decomposition (if sufficient workspace available)
                    501: *
                    502:          IF( M.GE.MNTHR1 ) THEN
                    503: *
                    504:             IF( WNTQN ) THEN
                    505: *
                    506: *              Path 1 (M much larger than N, JOBZ='N')
                    507: *              No singular vectors to be computed
                    508: *
                    509:                ITAU = 1
                    510:                NWORK = ITAU + N
                    511: *
                    512: *              Compute A=Q*R
                    513: *              (CWorkspace: need 2*N, prefer N+N*NB)
                    514: *              (RWorkspace: need 0)
                    515: *
                    516:                CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
                    517:      $                      LWORK-NWORK+1, IERR )
                    518: *
                    519: *              Zero out below R
                    520: *
                    521:                CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO, A( 2, 1 ),
                    522:      $                      LDA )
                    523:                IE = 1
                    524:                ITAUQ = 1
                    525:                ITAUP = ITAUQ + N
                    526:                NWORK = ITAUP + N
                    527: *
                    528: *              Bidiagonalize R in A
                    529: *              (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
                    530: *              (RWorkspace: need N)
                    531: *
                    532:                CALL ZGEBRD( N, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
                    533:      $                      WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
                    534:      $                      IERR )
                    535:                NRWORK = IE + N
                    536: *
                    537: *              Perform bidiagonal SVD, compute singular values only
                    538: *              (CWorkspace: 0)
                    539: *              (RWorkspace: need BDSPAN)
                    540: *
                    541:                CALL DBDSDC( 'U', 'N', N, S, RWORK( IE ), DUM, 1, DUM, 1,
                    542:      $                      DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
                    543: *
                    544:             ELSE IF( WNTQO ) THEN
                    545: *
                    546: *              Path 2 (M much larger than N, JOBZ='O')
                    547: *              N left singular vectors to be overwritten on A and
                    548: *              N right singular vectors to be computed in VT
                    549: *
                    550:                IU = 1
                    551: *
                    552: *              WORK(IU) is N by N
                    553: *
                    554:                LDWRKU = N
                    555:                IR = IU + LDWRKU*N
                    556:                IF( LWORK.GE.M*N+N*N+3*N ) THEN
                    557: *
                    558: *                 WORK(IR) is M by N
                    559: *
                    560:                   LDWRKR = M
                    561:                ELSE
                    562:                   LDWRKR = ( LWORK-N*N-3*N ) / N
                    563:                END IF
                    564:                ITAU = IR + LDWRKR*N
                    565:                NWORK = ITAU + N
                    566: *
                    567: *              Compute A=Q*R
                    568: *              (CWorkspace: need N*N+2*N, prefer M*N+N+N*NB)
                    569: *              (RWorkspace: 0)
                    570: *
                    571:                CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
                    572:      $                      LWORK-NWORK+1, IERR )
                    573: *
                    574: *              Copy R to WORK( IR ), zeroing out below it
                    575: *
                    576:                CALL ZLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )
                    577:                CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO, WORK( IR+1 ),
                    578:      $                      LDWRKR )
                    579: *
                    580: *              Generate Q in A
                    581: *              (CWorkspace: need 2*N, prefer N+N*NB)
                    582: *              (RWorkspace: 0)
                    583: *
                    584:                CALL ZUNGQR( M, N, N, A, LDA, WORK( ITAU ),
                    585:      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                    586:                IE = 1
                    587:                ITAUQ = ITAU
                    588:                ITAUP = ITAUQ + N
                    589:                NWORK = ITAUP + N
                    590: *
                    591: *              Bidiagonalize R in WORK(IR)
                    592: *              (CWorkspace: need N*N+3*N, prefer M*N+2*N+2*N*NB)
                    593: *              (RWorkspace: need N)
                    594: *
                    595:                CALL ZGEBRD( N, N, WORK( IR ), LDWRKR, S, RWORK( IE ),
                    596:      $                      WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
                    597:      $                      LWORK-NWORK+1, IERR )
                    598: *
                    599: *              Perform bidiagonal SVD, computing left singular vectors
                    600: *              of R in WORK(IRU) and computing right singular vectors
                    601: *              of R in WORK(IRVT)
                    602: *              (CWorkspace: need 0)
                    603: *              (RWorkspace: need BDSPAC)
                    604: *
                    605:                IRU = IE + N
                    606:                IRVT = IRU + N*N
                    607:                NRWORK = IRVT + N*N
                    608:                CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
                    609:      $                      N, RWORK( IRVT ), N, DUM, IDUM,
                    610:      $                      RWORK( NRWORK ), IWORK, INFO )
                    611: *
                    612: *              Copy real matrix RWORK(IRU) to complex matrix WORK(IU)
                    613: *              Overwrite WORK(IU) by the left singular vectors of R
                    614: *              (CWorkspace: need 2*N*N+3*N, prefer M*N+N*N+2*N+N*NB)
                    615: *              (RWorkspace: 0)
                    616: *
                    617:                CALL ZLACP2( 'F', N, N, RWORK( IRU ), N, WORK( IU ),
                    618:      $                      LDWRKU )
                    619:                CALL ZUNMBR( 'Q', 'L', 'N', N, N, N, WORK( IR ), LDWRKR,
                    620:      $                      WORK( ITAUQ ), WORK( IU ), LDWRKU,
                    621:      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                    622: *
                    623: *              Copy real matrix RWORK(IRVT) to complex matrix VT
                    624: *              Overwrite VT by the right singular vectors of R
                    625: *              (CWorkspace: need N*N+3*N, prefer M*N+2*N+N*NB)
                    626: *              (RWorkspace: 0)
                    627: *
                    628:                CALL ZLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
                    629:                CALL ZUNMBR( 'P', 'R', 'C', N, N, N, WORK( IR ), LDWRKR,
                    630:      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
                    631:      $                      LWORK-NWORK+1, IERR )
                    632: *
                    633: *              Multiply Q in A by left singular vectors of R in
                    634: *              WORK(IU), storing result in WORK(IR) and copying to A
                    635: *              (CWorkspace: need 2*N*N, prefer N*N+M*N)
                    636: *              (RWorkspace: 0)
                    637: *
                    638:                DO 10 I = 1, M, LDWRKR
                    639:                   CHUNK = MIN( M-I+1, LDWRKR )
                    640:                   CALL ZGEMM( 'N', 'N', CHUNK, N, N, CONE, A( I, 1 ),
                    641:      $                        LDA, WORK( IU ), LDWRKU, CZERO,
                    642:      $                        WORK( IR ), LDWRKR )
                    643:                   CALL ZLACPY( 'F', CHUNK, N, WORK( IR ), LDWRKR,
                    644:      $                         A( I, 1 ), LDA )
                    645:    10          CONTINUE
                    646: *
                    647:             ELSE IF( WNTQS ) THEN
                    648: *
                    649: *              Path 3 (M much larger than N, JOBZ='S')
                    650: *              N left singular vectors to be computed in U and
                    651: *              N right singular vectors to be computed in VT
                    652: *
                    653:                IR = 1
                    654: *
                    655: *              WORK(IR) is N by N
                    656: *
                    657:                LDWRKR = N
                    658:                ITAU = IR + LDWRKR*N
                    659:                NWORK = ITAU + N
                    660: *
                    661: *              Compute A=Q*R
                    662: *              (CWorkspace: need N*N+2*N, prefer N*N+N+N*NB)
                    663: *              (RWorkspace: 0)
                    664: *
                    665:                CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
                    666:      $                      LWORK-NWORK+1, IERR )
                    667: *
                    668: *              Copy R to WORK(IR), zeroing out below it
                    669: *
                    670:                CALL ZLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )
                    671:                CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO, WORK( IR+1 ),
                    672:      $                      LDWRKR )
                    673: *
                    674: *              Generate Q in A
                    675: *              (CWorkspace: need 2*N, prefer N+N*NB)
                    676: *              (RWorkspace: 0)
                    677: *
                    678:                CALL ZUNGQR( M, N, N, A, LDA, WORK( ITAU ),
                    679:      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                    680:                IE = 1
                    681:                ITAUQ = ITAU
                    682:                ITAUP = ITAUQ + N
                    683:                NWORK = ITAUP + N
                    684: *
                    685: *              Bidiagonalize R in WORK(IR)
                    686: *              (CWorkspace: need N*N+3*N, prefer N*N+2*N+2*N*NB)
                    687: *              (RWorkspace: need N)
                    688: *
                    689:                CALL ZGEBRD( N, N, WORK( IR ), LDWRKR, S, RWORK( IE ),
                    690:      $                      WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
                    691:      $                      LWORK-NWORK+1, IERR )
                    692: *
                    693: *              Perform bidiagonal SVD, computing left singular vectors
                    694: *              of bidiagonal matrix in RWORK(IRU) and computing right
                    695: *              singular vectors of bidiagonal matrix in RWORK(IRVT)
                    696: *              (CWorkspace: need 0)
                    697: *              (RWorkspace: need BDSPAC)
                    698: *
                    699:                IRU = IE + N
                    700:                IRVT = IRU + N*N
                    701:                NRWORK = IRVT + N*N
                    702:                CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
                    703:      $                      N, RWORK( IRVT ), N, DUM, IDUM,
                    704:      $                      RWORK( NRWORK ), IWORK, INFO )
                    705: *
                    706: *              Copy real matrix RWORK(IRU) to complex matrix U
                    707: *              Overwrite U by left singular vectors of R
                    708: *              (CWorkspace: need N*N+3*N, prefer N*N+2*N+N*NB)
                    709: *              (RWorkspace: 0)
                    710: *
                    711:                CALL ZLACP2( 'F', N, N, RWORK( IRU ), N, U, LDU )
                    712:                CALL ZUNMBR( 'Q', 'L', 'N', N, N, N, WORK( IR ), LDWRKR,
                    713:      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
                    714:      $                      LWORK-NWORK+1, IERR )
                    715: *
                    716: *              Copy real matrix RWORK(IRVT) to complex matrix VT
                    717: *              Overwrite VT by right singular vectors of R
                    718: *              (CWorkspace: need N*N+3*N, prefer N*N+2*N+N*NB)
                    719: *              (RWorkspace: 0)
                    720: *
                    721:                CALL ZLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
                    722:                CALL ZUNMBR( 'P', 'R', 'C', N, N, N, WORK( IR ), LDWRKR,
                    723:      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
                    724:      $                      LWORK-NWORK+1, IERR )
                    725: *
                    726: *              Multiply Q in A by left singular vectors of R in
                    727: *              WORK(IR), storing result in U
                    728: *              (CWorkspace: need N*N)
                    729: *              (RWorkspace: 0)
                    730: *
                    731:                CALL ZLACPY( 'F', N, N, U, LDU, WORK( IR ), LDWRKR )
                    732:                CALL ZGEMM( 'N', 'N', M, N, N, CONE, A, LDA, WORK( IR ),
                    733:      $                     LDWRKR, CZERO, U, LDU )
                    734: *
                    735:             ELSE IF( WNTQA ) THEN
                    736: *
                    737: *              Path 4 (M much larger than N, JOBZ='A')
                    738: *              M left singular vectors to be computed in U and
                    739: *              N right singular vectors to be computed in VT
                    740: *
                    741:                IU = 1
                    742: *
                    743: *              WORK(IU) is N by N
                    744: *
                    745:                LDWRKU = N
                    746:                ITAU = IU + LDWRKU*N
                    747:                NWORK = ITAU + N
                    748: *
                    749: *              Compute A=Q*R, copying result to U
                    750: *              (CWorkspace: need 2*N, prefer N+N*NB)
                    751: *              (RWorkspace: 0)
                    752: *
                    753:                CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
                    754:      $                      LWORK-NWORK+1, IERR )
                    755:                CALL ZLACPY( 'L', M, N, A, LDA, U, LDU )
                    756: *
                    757: *              Generate Q in U
                    758: *              (CWorkspace: need N+M, prefer N+M*NB)
                    759: *              (RWorkspace: 0)
                    760: *
                    761:                CALL ZUNGQR( M, M, N, U, LDU, WORK( ITAU ),
                    762:      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                    763: *
                    764: *              Produce R in A, zeroing out below it
                    765: *
                    766:                CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO, A( 2, 1 ),
                    767:      $                      LDA )
                    768:                IE = 1
                    769:                ITAUQ = ITAU
                    770:                ITAUP = ITAUQ + N
                    771:                NWORK = ITAUP + N
                    772: *
                    773: *              Bidiagonalize R in A
                    774: *              (CWorkspace: need 3*N, prefer 2*N+2*N*NB)
                    775: *              (RWorkspace: need N)
                    776: *
                    777:                CALL ZGEBRD( N, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
                    778:      $                      WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
                    779:      $                      IERR )
                    780:                IRU = IE + N
                    781:                IRVT = IRU + N*N
                    782:                NRWORK = IRVT + N*N
                    783: *
                    784: *              Perform bidiagonal SVD, computing left singular vectors
                    785: *              of bidiagonal matrix in RWORK(IRU) and computing right
                    786: *              singular vectors of bidiagonal matrix in RWORK(IRVT)
                    787: *              (CWorkspace: need 0)
                    788: *              (RWorkspace: need BDSPAC)
                    789: *
                    790:                CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
                    791:      $                      N, RWORK( IRVT ), N, DUM, IDUM,
                    792:      $                      RWORK( NRWORK ), IWORK, INFO )
                    793: *
                    794: *              Copy real matrix RWORK(IRU) to complex matrix WORK(IU)
                    795: *              Overwrite WORK(IU) by left singular vectors of R
                    796: *              (CWorkspace: need N*N+3*N, prefer N*N+2*N+N*NB)
                    797: *              (RWorkspace: 0)
                    798: *
                    799:                CALL ZLACP2( 'F', N, N, RWORK( IRU ), N, WORK( IU ),
                    800:      $                      LDWRKU )
                    801:                CALL ZUNMBR( 'Q', 'L', 'N', N, N, N, A, LDA,
                    802:      $                      WORK( ITAUQ ), WORK( IU ), LDWRKU,
                    803:      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                    804: *
                    805: *              Copy real matrix RWORK(IRVT) to complex matrix VT
                    806: *              Overwrite VT by right singular vectors of R
                    807: *              (CWorkspace: need 3*N, prefer 2*N+N*NB)
                    808: *              (RWorkspace: 0)
                    809: *
                    810:                CALL ZLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
                    811:                CALL ZUNMBR( 'P', 'R', 'C', N, N, N, A, LDA,
                    812:      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
                    813:      $                      LWORK-NWORK+1, IERR )
                    814: *
                    815: *              Multiply Q in U by left singular vectors of R in
                    816: *              WORK(IU), storing result in A
                    817: *              (CWorkspace: need N*N)
                    818: *              (RWorkspace: 0)
                    819: *
                    820:                CALL ZGEMM( 'N', 'N', M, N, N, CONE, U, LDU, WORK( IU ),
                    821:      $                     LDWRKU, CZERO, A, LDA )
                    822: *
                    823: *              Copy left singular vectors of A from A to U
                    824: *
                    825:                CALL ZLACPY( 'F', M, N, A, LDA, U, LDU )
                    826: *
                    827:             END IF
                    828: *
                    829:          ELSE IF( M.GE.MNTHR2 ) THEN
                    830: *
                    831: *           MNTHR2 <= M < MNTHR1
                    832: *
                    833: *           Path 5 (M much larger than N, but not as much as MNTHR1)
                    834: *           Reduce to bidiagonal form without QR decomposition, use
                    835: *           ZUNGBR and matrix multiplication to compute singular vectors
                    836: *
                    837:             IE = 1
                    838:             NRWORK = IE + N
                    839:             ITAUQ = 1
                    840:             ITAUP = ITAUQ + N
                    841:             NWORK = ITAUP + N
                    842: *
                    843: *           Bidiagonalize A
                    844: *           (CWorkspace: need 2*N+M, prefer 2*N+(M+N)*NB)
                    845: *           (RWorkspace: need N)
                    846: *
                    847:             CALL ZGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
                    848:      $                   WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
                    849:      $                   IERR )
                    850:             IF( WNTQN ) THEN
                    851: *
                    852: *              Compute singular values only
                    853: *              (Cworkspace: 0)
                    854: *              (Rworkspace: need BDSPAN)
                    855: *
                    856:                CALL DBDSDC( 'U', 'N', N, S, RWORK( IE ), DUM, 1, DUM, 1,
                    857:      $                      DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
                    858:             ELSE IF( WNTQO ) THEN
                    859:                IU = NWORK
                    860:                IRU = NRWORK
                    861:                IRVT = IRU + N*N
                    862:                NRWORK = IRVT + N*N
                    863: *
                    864: *              Copy A to VT, generate P**H
                    865: *              (Cworkspace: need 2*N, prefer N+N*NB)
                    866: *              (Rworkspace: 0)
                    867: *
                    868:                CALL ZLACPY( 'U', N, N, A, LDA, VT, LDVT )
                    869:                CALL ZUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
                    870:      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                    871: *
                    872: *              Generate Q in A
                    873: *              (CWorkspace: need 2*N, prefer N+N*NB)
                    874: *              (RWorkspace: 0)
                    875: *
                    876:                CALL ZUNGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
                    877:      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                    878: *
                    879:                IF( LWORK.GE.M*N+3*N ) THEN
                    880: *
                    881: *                 WORK( IU ) is M by N
                    882: *
                    883:                   LDWRKU = M
                    884:                ELSE
                    885: *
                    886: *                 WORK(IU) is LDWRKU by N
                    887: *
                    888:                   LDWRKU = ( LWORK-3*N ) / N
                    889:                END IF
                    890:                NWORK = IU + LDWRKU*N
                    891: *
                    892: *              Perform bidiagonal SVD, computing left singular vectors
                    893: *              of bidiagonal matrix in RWORK(IRU) and computing right
                    894: *              singular vectors of bidiagonal matrix in RWORK(IRVT)
                    895: *              (CWorkspace: need 0)
                    896: *              (RWorkspace: need BDSPAC)
                    897: *
                    898:                CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
                    899:      $                      N, RWORK( IRVT ), N, DUM, IDUM,
                    900:      $                      RWORK( NRWORK ), IWORK, INFO )
                    901: *
                    902: *              Multiply real matrix RWORK(IRVT) by P**H in VT,
                    903: *              storing the result in WORK(IU), copying to VT
                    904: *              (Cworkspace: need 0)
                    905: *              (Rworkspace: need 3*N*N)
                    906: *
                    907:                CALL ZLARCM( N, N, RWORK( IRVT ), N, VT, LDVT,
                    908:      $                      WORK( IU ), LDWRKU, RWORK( NRWORK ) )
                    909:                CALL ZLACPY( 'F', N, N, WORK( IU ), LDWRKU, VT, LDVT )
                    910: *
                    911: *              Multiply Q in A by real matrix RWORK(IRU), storing the
                    912: *              result in WORK(IU), copying to A
                    913: *              (CWorkspace: need N*N, prefer M*N)
                    914: *              (Rworkspace: need 3*N*N, prefer N*N+2*M*N)
                    915: *
                    916:                NRWORK = IRVT
                    917:                DO 20 I = 1, M, LDWRKU
                    918:                   CHUNK = MIN( M-I+1, LDWRKU )
                    919:                   CALL ZLACRM( CHUNK, N, A( I, 1 ), LDA, RWORK( IRU ),
                    920:      $                         N, WORK( IU ), LDWRKU, RWORK( NRWORK ) )
                    921:                   CALL ZLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,
                    922:      $                         A( I, 1 ), LDA )
                    923:    20          CONTINUE
                    924: *
                    925:             ELSE IF( WNTQS ) THEN
                    926: *
                    927: *              Copy A to VT, generate P**H
                    928: *              (Cworkspace: need 2*N, prefer N+N*NB)
                    929: *              (Rworkspace: 0)
                    930: *
                    931:                CALL ZLACPY( 'U', N, N, A, LDA, VT, LDVT )
                    932:                CALL ZUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
                    933:      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                    934: *
                    935: *              Copy A to U, generate Q
                    936: *              (Cworkspace: need 2*N, prefer N+N*NB)
                    937: *              (Rworkspace: 0)
                    938: *
                    939:                CALL ZLACPY( 'L', M, N, A, LDA, U, LDU )
                    940:                CALL ZUNGBR( 'Q', M, N, N, U, LDU, WORK( ITAUQ ),
                    941:      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                    942: *
                    943: *              Perform bidiagonal SVD, computing left singular vectors
                    944: *              of bidiagonal matrix in RWORK(IRU) and computing right
                    945: *              singular vectors of bidiagonal matrix in RWORK(IRVT)
                    946: *              (CWorkspace: need 0)
                    947: *              (RWorkspace: need BDSPAC)
                    948: *
                    949:                IRU = NRWORK
                    950:                IRVT = IRU + N*N
                    951:                NRWORK = IRVT + N*N
                    952:                CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
                    953:      $                      N, RWORK( IRVT ), N, DUM, IDUM,
                    954:      $                      RWORK( NRWORK ), IWORK, INFO )
                    955: *
                    956: *              Multiply real matrix RWORK(IRVT) by P**H in VT,
                    957: *              storing the result in A, copying to VT
                    958: *              (Cworkspace: need 0)
                    959: *              (Rworkspace: need 3*N*N)
                    960: *
                    961:                CALL ZLARCM( N, N, RWORK( IRVT ), N, VT, LDVT, A, LDA,
                    962:      $                      RWORK( NRWORK ) )
                    963:                CALL ZLACPY( 'F', N, N, A, LDA, VT, LDVT )
                    964: *
                    965: *              Multiply Q in U by real matrix RWORK(IRU), storing the
                    966: *              result in A, copying to U
                    967: *              (CWorkspace: need 0)
                    968: *              (Rworkspace: need N*N+2*M*N)
                    969: *
                    970:                NRWORK = IRVT
                    971:                CALL ZLACRM( M, N, U, LDU, RWORK( IRU ), N, A, LDA,
                    972:      $                      RWORK( NRWORK ) )
                    973:                CALL ZLACPY( 'F', M, N, A, LDA, U, LDU )
                    974:             ELSE
                    975: *
                    976: *              Copy A to VT, generate P**H
                    977: *              (Cworkspace: need 2*N, prefer N+N*NB)
                    978: *              (Rworkspace: 0)
                    979: *
                    980:                CALL ZLACPY( 'U', N, N, A, LDA, VT, LDVT )
                    981:                CALL ZUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
                    982:      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                    983: *
                    984: *              Copy A to U, generate Q
                    985: *              (Cworkspace: need 2*N, prefer N+N*NB)
                    986: *              (Rworkspace: 0)
                    987: *
                    988:                CALL ZLACPY( 'L', M, N, A, LDA, U, LDU )
                    989:                CALL ZUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
                    990:      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                    991: *
                    992: *              Perform bidiagonal SVD, computing left singular vectors
                    993: *              of bidiagonal matrix in RWORK(IRU) and computing right
                    994: *              singular vectors of bidiagonal matrix in RWORK(IRVT)
                    995: *              (CWorkspace: need 0)
                    996: *              (RWorkspace: need BDSPAC)
                    997: *
                    998:                IRU = NRWORK
                    999:                IRVT = IRU + N*N
                   1000:                NRWORK = IRVT + N*N
                   1001:                CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
                   1002:      $                      N, RWORK( IRVT ), N, DUM, IDUM,
                   1003:      $                      RWORK( NRWORK ), IWORK, INFO )
                   1004: *
                   1005: *              Multiply real matrix RWORK(IRVT) by P**H in VT,
                   1006: *              storing the result in A, copying to VT
                   1007: *              (Cworkspace: need 0)
                   1008: *              (Rworkspace: need 3*N*N)
                   1009: *
                   1010:                CALL ZLARCM( N, N, RWORK( IRVT ), N, VT, LDVT, A, LDA,
                   1011:      $                      RWORK( NRWORK ) )
                   1012:                CALL ZLACPY( 'F', N, N, A, LDA, VT, LDVT )
                   1013: *
                   1014: *              Multiply Q in U by real matrix RWORK(IRU), storing the
                   1015: *              result in A, copying to U
                   1016: *              (CWorkspace: 0)
                   1017: *              (Rworkspace: need 3*N*N)
                   1018: *
                   1019:                NRWORK = IRVT
                   1020:                CALL ZLACRM( M, N, U, LDU, RWORK( IRU ), N, A, LDA,
                   1021:      $                      RWORK( NRWORK ) )
                   1022:                CALL ZLACPY( 'F', M, N, A, LDA, U, LDU )
                   1023:             END IF
                   1024: *
                   1025:          ELSE
                   1026: *
                   1027: *           M .LT. MNTHR2
                   1028: *
                   1029: *           Path 6 (M at least N, but not much larger)
                   1030: *           Reduce to bidiagonal form without QR decomposition
                   1031: *           Use ZUNMBR to compute singular vectors
                   1032: *
                   1033:             IE = 1
                   1034:             NRWORK = IE + N
                   1035:             ITAUQ = 1
                   1036:             ITAUP = ITAUQ + N
                   1037:             NWORK = ITAUP + N
                   1038: *
                   1039: *           Bidiagonalize A
                   1040: *           (CWorkspace: need 2*N+M, prefer 2*N+(M+N)*NB)
                   1041: *           (RWorkspace: need N)
                   1042: *
                   1043:             CALL ZGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
                   1044:      $                   WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
                   1045:      $                   IERR )
                   1046:             IF( WNTQN ) THEN
                   1047: *
                   1048: *              Compute singular values only
                   1049: *              (Cworkspace: 0)
                   1050: *              (Rworkspace: need BDSPAN)
                   1051: *
                   1052:                CALL DBDSDC( 'U', 'N', N, S, RWORK( IE ), DUM, 1, DUM, 1,
                   1053:      $                      DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
                   1054:             ELSE IF( WNTQO ) THEN
                   1055:                IU = NWORK
                   1056:                IRU = NRWORK
                   1057:                IRVT = IRU + N*N
                   1058:                NRWORK = IRVT + N*N
                   1059:                IF( LWORK.GE.M*N+3*N ) THEN
                   1060: *
                   1061: *                 WORK( IU ) is M by N
                   1062: *
                   1063:                   LDWRKU = M
                   1064:                ELSE
                   1065: *
                   1066: *                 WORK( IU ) is LDWRKU by N
                   1067: *
                   1068:                   LDWRKU = ( LWORK-3*N ) / N
                   1069:                END IF
                   1070:                NWORK = IU + LDWRKU*N
                   1071: *
                   1072: *              Perform bidiagonal SVD, computing left singular vectors
                   1073: *              of bidiagonal matrix in RWORK(IRU) and computing right
                   1074: *              singular vectors of bidiagonal matrix in RWORK(IRVT)
                   1075: *              (CWorkspace: need 0)
                   1076: *              (RWorkspace: need BDSPAC)
                   1077: *
                   1078:                CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
                   1079:      $                      N, RWORK( IRVT ), N, DUM, IDUM,
                   1080:      $                      RWORK( NRWORK ), IWORK, INFO )
                   1081: *
                   1082: *              Copy real matrix RWORK(IRVT) to complex matrix VT
                   1083: *              Overwrite VT by right singular vectors of A
                   1084: *              (Cworkspace: need 2*N, prefer N+N*NB)
                   1085: *              (Rworkspace: need 0)
                   1086: *
                   1087:                CALL ZLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
                   1088:                CALL ZUNMBR( 'P', 'R', 'C', N, N, N, A, LDA,
                   1089:      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
                   1090:      $                      LWORK-NWORK+1, IERR )
                   1091: *
                   1092:                IF( LWORK.GE.M*N+3*N ) THEN
                   1093: *
                   1094: *              Copy real matrix RWORK(IRU) to complex matrix WORK(IU)
                   1095: *              Overwrite WORK(IU) by left singular vectors of A, copying
                   1096: *              to A
                   1097: *              (Cworkspace: need M*N+2*N, prefer M*N+N+N*NB)
                   1098: *              (Rworkspace: need 0)
                   1099: *
                   1100:                   CALL ZLASET( 'F', M, N, CZERO, CZERO, WORK( IU ),
                   1101:      $                         LDWRKU )
                   1102:                   CALL ZLACP2( 'F', N, N, RWORK( IRU ), N, WORK( IU ),
                   1103:      $                         LDWRKU )
                   1104:                   CALL ZUNMBR( 'Q', 'L', 'N', M, N, N, A, LDA,
                   1105:      $                         WORK( ITAUQ ), WORK( IU ), LDWRKU,
                   1106:      $                         WORK( NWORK ), LWORK-NWORK+1, IERR )
                   1107:                   CALL ZLACPY( 'F', M, N, WORK( IU ), LDWRKU, A, LDA )
                   1108:                ELSE
                   1109: *
                   1110: *                 Generate Q in A
                   1111: *                 (Cworkspace: need 2*N, prefer N+N*NB)
                   1112: *                 (Rworkspace: need 0)
                   1113: *
                   1114:                   CALL ZUNGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
                   1115:      $                         WORK( NWORK ), LWORK-NWORK+1, IERR )
                   1116: *
                   1117: *                 Multiply Q in A by real matrix RWORK(IRU), storing the
                   1118: *                 result in WORK(IU), copying to A
                   1119: *                 (CWorkspace: need N*N, prefer M*N)
                   1120: *                 (Rworkspace: need 3*N*N, prefer N*N+2*M*N)
                   1121: *
                   1122:                   NRWORK = IRVT
                   1123:                   DO 30 I = 1, M, LDWRKU
                   1124:                      CHUNK = MIN( M-I+1, LDWRKU )
                   1125:                      CALL ZLACRM( CHUNK, N, A( I, 1 ), LDA,
                   1126:      $                            RWORK( IRU ), N, WORK( IU ), LDWRKU,
                   1127:      $                            RWORK( NRWORK ) )
                   1128:                      CALL ZLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,
                   1129:      $                            A( I, 1 ), LDA )
                   1130:    30             CONTINUE
                   1131:                END IF
                   1132: *
                   1133:             ELSE IF( WNTQS ) THEN
                   1134: *
                   1135: *              Perform bidiagonal SVD, computing left singular vectors
                   1136: *              of bidiagonal matrix in RWORK(IRU) and computing right
                   1137: *              singular vectors of bidiagonal matrix in RWORK(IRVT)
                   1138: *              (CWorkspace: need 0)
                   1139: *              (RWorkspace: need BDSPAC)
                   1140: *
                   1141:                IRU = NRWORK
                   1142:                IRVT = IRU + N*N
                   1143:                NRWORK = IRVT + N*N
                   1144:                CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
                   1145:      $                      N, RWORK( IRVT ), N, DUM, IDUM,
                   1146:      $                      RWORK( NRWORK ), IWORK, INFO )
                   1147: *
                   1148: *              Copy real matrix RWORK(IRU) to complex matrix U
                   1149: *              Overwrite U by left singular vectors of A
                   1150: *              (CWorkspace: need 3*N, prefer 2*N+N*NB)
                   1151: *              (RWorkspace: 0)
                   1152: *
                   1153:                CALL ZLASET( 'F', M, N, CZERO, CZERO, U, LDU )
                   1154:                CALL ZLACP2( 'F', N, N, RWORK( IRU ), N, U, LDU )
                   1155:                CALL ZUNMBR( 'Q', 'L', 'N', M, N, N, A, LDA,
                   1156:      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
                   1157:      $                      LWORK-NWORK+1, IERR )
                   1158: *
                   1159: *              Copy real matrix RWORK(IRVT) to complex matrix VT
                   1160: *              Overwrite VT by right singular vectors of A
                   1161: *              (CWorkspace: need 3*N, prefer 2*N+N*NB)
                   1162: *              (RWorkspace: 0)
                   1163: *
                   1164:                CALL ZLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
                   1165:                CALL ZUNMBR( 'P', 'R', 'C', N, N, N, A, LDA,
                   1166:      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
                   1167:      $                      LWORK-NWORK+1, IERR )
                   1168:             ELSE
                   1169: *
                   1170: *              Perform bidiagonal SVD, computing left singular vectors
                   1171: *              of bidiagonal matrix in RWORK(IRU) and computing right
                   1172: *              singular vectors of bidiagonal matrix in RWORK(IRVT)
                   1173: *              (CWorkspace: need 0)
                   1174: *              (RWorkspace: need BDSPAC)
                   1175: *
                   1176:                IRU = NRWORK
                   1177:                IRVT = IRU + N*N
                   1178:                NRWORK = IRVT + N*N
                   1179:                CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
                   1180:      $                      N, RWORK( IRVT ), N, DUM, IDUM,
                   1181:      $                      RWORK( NRWORK ), IWORK, INFO )
                   1182: *
                   1183: *              Set the right corner of U to identity matrix
                   1184: *
                   1185:                CALL ZLASET( 'F', M, M, CZERO, CZERO, U, LDU )
                   1186:                IF( M.GT.N ) THEN
                   1187:                   CALL ZLASET( 'F', M-N, M-N, CZERO, CONE,
                   1188:      $                         U( N+1, N+1 ), LDU )
                   1189:                END IF
                   1190: *
                   1191: *              Copy real matrix RWORK(IRU) to complex matrix U
                   1192: *              Overwrite U by left singular vectors of A
                   1193: *              (CWorkspace: need 2*N+M, prefer 2*N+M*NB)
                   1194: *              (RWorkspace: 0)
                   1195: *
                   1196:                CALL ZLACP2( 'F', N, N, RWORK( IRU ), N, U, LDU )
                   1197:                CALL ZUNMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
                   1198:      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
                   1199:      $                      LWORK-NWORK+1, IERR )
                   1200: *
                   1201: *              Copy real matrix RWORK(IRVT) to complex matrix VT
                   1202: *              Overwrite VT by right singular vectors of A
                   1203: *              (CWorkspace: need 3*N, prefer 2*N+N*NB)
                   1204: *              (RWorkspace: 0)
                   1205: *
                   1206:                CALL ZLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
                   1207:                CALL ZUNMBR( 'P', 'R', 'C', N, N, N, A, LDA,
                   1208:      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
                   1209:      $                      LWORK-NWORK+1, IERR )
                   1210:             END IF
                   1211: *
                   1212:          END IF
                   1213: *
                   1214:       ELSE
                   1215: *
                   1216: *        A has more columns than rows. If A has sufficiently more
                   1217: *        columns than rows, first reduce using the LQ decomposition (if
                   1218: *        sufficient workspace available)
                   1219: *
                   1220:          IF( N.GE.MNTHR1 ) THEN
                   1221: *
                   1222:             IF( WNTQN ) THEN
                   1223: *
                   1224: *              Path 1t (N much larger than M, JOBZ='N')
                   1225: *              No singular vectors to be computed
                   1226: *
                   1227:                ITAU = 1
                   1228:                NWORK = ITAU + M
                   1229: *
                   1230: *              Compute A=L*Q
                   1231: *              (CWorkspace: need 2*M, prefer M+M*NB)
                   1232: *              (RWorkspace: 0)
                   1233: *
                   1234:                CALL ZGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
                   1235:      $                      LWORK-NWORK+1, IERR )
                   1236: *
                   1237: *              Zero out above L
                   1238: *
                   1239:                CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO, A( 1, 2 ),
                   1240:      $                      LDA )
                   1241:                IE = 1
                   1242:                ITAUQ = 1
                   1243:                ITAUP = ITAUQ + M
                   1244:                NWORK = ITAUP + M
                   1245: *
                   1246: *              Bidiagonalize L in A
                   1247: *              (CWorkspace: need 3*M, prefer 2*M+2*M*NB)
                   1248: *              (RWorkspace: need M)
                   1249: *
                   1250:                CALL ZGEBRD( M, M, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
                   1251:      $                      WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
                   1252:      $                      IERR )
                   1253:                NRWORK = IE + M
                   1254: *
                   1255: *              Perform bidiagonal SVD, compute singular values only
                   1256: *              (CWorkspace: 0)
                   1257: *              (RWorkspace: need BDSPAN)
                   1258: *
                   1259:                CALL DBDSDC( 'U', 'N', M, S, RWORK( IE ), DUM, 1, DUM, 1,
                   1260:      $                      DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
                   1261: *
                   1262:             ELSE IF( WNTQO ) THEN
                   1263: *
                   1264: *              Path 2t (N much larger than M, JOBZ='O')
                   1265: *              M right singular vectors to be overwritten on A and
                   1266: *              M left singular vectors to be computed in U
                   1267: *
                   1268:                IVT = 1
                   1269:                LDWKVT = M
                   1270: *
                   1271: *              WORK(IVT) is M by M
                   1272: *
                   1273:                IL = IVT + LDWKVT*M
                   1274:                IF( LWORK.GE.M*N+M*M+3*M ) THEN
                   1275: *
                   1276: *                 WORK(IL) M by N
                   1277: *
                   1278:                   LDWRKL = M
                   1279:                   CHUNK = N
                   1280:                ELSE
                   1281: *
                   1282: *                 WORK(IL) is M by CHUNK
                   1283: *
                   1284:                   LDWRKL = M
                   1285:                   CHUNK = ( LWORK-M*M-3*M ) / M
                   1286:                END IF
                   1287:                ITAU = IL + LDWRKL*CHUNK
                   1288:                NWORK = ITAU + M
                   1289: *
                   1290: *              Compute A=L*Q
                   1291: *              (CWorkspace: need 2*M, prefer M+M*NB)
                   1292: *              (RWorkspace: 0)
                   1293: *
                   1294:                CALL ZGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
                   1295:      $                      LWORK-NWORK+1, IERR )
                   1296: *
                   1297: *              Copy L to WORK(IL), zeroing about above it
                   1298: *
                   1299:                CALL ZLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWRKL )
                   1300:                CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO,
                   1301:      $                      WORK( IL+LDWRKL ), LDWRKL )
                   1302: *
                   1303: *              Generate Q in A
                   1304: *              (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
                   1305: *              (RWorkspace: 0)
                   1306: *
                   1307:                CALL ZUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
                   1308:      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                   1309:                IE = 1
                   1310:                ITAUQ = ITAU
                   1311:                ITAUP = ITAUQ + M
                   1312:                NWORK = ITAUP + M
                   1313: *
                   1314: *              Bidiagonalize L in WORK(IL)
                   1315: *              (CWorkspace: need M*M+3*M, prefer M*M+2*M+2*M*NB)
                   1316: *              (RWorkspace: need M)
                   1317: *
                   1318:                CALL ZGEBRD( M, M, WORK( IL ), LDWRKL, S, RWORK( IE ),
                   1319:      $                      WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
                   1320:      $                      LWORK-NWORK+1, IERR )
                   1321: *
                   1322: *              Perform bidiagonal SVD, computing left singular vectors
                   1323: *              of bidiagonal matrix in RWORK(IRU) and computing right
                   1324: *              singular vectors of bidiagonal matrix in RWORK(IRVT)
                   1325: *              (CWorkspace: need 0)
                   1326: *              (RWorkspace: need BDSPAC)
                   1327: *
                   1328:                IRU = IE + M
                   1329:                IRVT = IRU + M*M
                   1330:                NRWORK = IRVT + M*M
                   1331:                CALL DBDSDC( 'U', 'I', M, S, RWORK( IE ), RWORK( IRU ),
                   1332:      $                      M, RWORK( IRVT ), M, DUM, IDUM,
                   1333:      $                      RWORK( NRWORK ), IWORK, INFO )
                   1334: *
                   1335: *              Copy real matrix RWORK(IRU) to complex matrix WORK(IU)
                   1336: *              Overwrite WORK(IU) by the left singular vectors of L
                   1337: *              (CWorkspace: need N*N+3*N, prefer M*N+2*N+N*NB)
                   1338: *              (RWorkspace: 0)
                   1339: *
                   1340:                CALL ZLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
                   1341:                CALL ZUNMBR( 'Q', 'L', 'N', M, M, M, WORK( IL ), LDWRKL,
                   1342:      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
                   1343:      $                      LWORK-NWORK+1, IERR )
                   1344: *
                   1345: *              Copy real matrix RWORK(IRVT) to complex matrix WORK(IVT)
                   1346: *              Overwrite WORK(IVT) by the right singular vectors of L
                   1347: *              (CWorkspace: need N*N+3*N, prefer M*N+2*N+N*NB)
                   1348: *              (RWorkspace: 0)
                   1349: *
                   1350:                CALL ZLACP2( 'F', M, M, RWORK( IRVT ), M, WORK( IVT ),
                   1351:      $                      LDWKVT )
                   1352:                CALL ZUNMBR( 'P', 'R', 'C', M, M, M, WORK( IL ), LDWRKL,
                   1353:      $                      WORK( ITAUP ), WORK( IVT ), LDWKVT,
                   1354:      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                   1355: *
                   1356: *              Multiply right singular vectors of L in WORK(IL) by Q
                   1357: *              in A, storing result in WORK(IL) and copying to A
                   1358: *              (CWorkspace: need 2*M*M, prefer M*M+M*N))
                   1359: *              (RWorkspace: 0)
                   1360: *
                   1361:                DO 40 I = 1, N, CHUNK
                   1362:                   BLK = MIN( N-I+1, CHUNK )
                   1363:                   CALL ZGEMM( 'N', 'N', M, BLK, M, CONE, WORK( IVT ), M,
                   1364:      $                        A( 1, I ), LDA, CZERO, WORK( IL ),
                   1365:      $                        LDWRKL )
                   1366:                   CALL ZLACPY( 'F', M, BLK, WORK( IL ), LDWRKL,
                   1367:      $                         A( 1, I ), LDA )
                   1368:    40          CONTINUE
                   1369: *
                   1370:             ELSE IF( WNTQS ) THEN
                   1371: *
                   1372: *             Path 3t (N much larger than M, JOBZ='S')
                   1373: *             M right singular vectors to be computed in VT and
                   1374: *             M left singular vectors to be computed in U
                   1375: *
                   1376:                IL = 1
                   1377: *
                   1378: *              WORK(IL) is M by M
                   1379: *
                   1380:                LDWRKL = M
                   1381:                ITAU = IL + LDWRKL*M
                   1382:                NWORK = ITAU + M
                   1383: *
                   1384: *              Compute A=L*Q
                   1385: *              (CWorkspace: need 2*M, prefer M+M*NB)
                   1386: *              (RWorkspace: 0)
                   1387: *
                   1388:                CALL ZGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
                   1389:      $                      LWORK-NWORK+1, IERR )
                   1390: *
                   1391: *              Copy L to WORK(IL), zeroing out above it
                   1392: *
                   1393:                CALL ZLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWRKL )
                   1394:                CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO,
                   1395:      $                      WORK( IL+LDWRKL ), LDWRKL )
                   1396: *
                   1397: *              Generate Q in A
                   1398: *              (CWorkspace: need M*M+2*M, prefer M*M+M+M*NB)
                   1399: *              (RWorkspace: 0)
                   1400: *
                   1401:                CALL ZUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
                   1402:      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                   1403:                IE = 1
                   1404:                ITAUQ = ITAU
                   1405:                ITAUP = ITAUQ + M
                   1406:                NWORK = ITAUP + M
                   1407: *
                   1408: *              Bidiagonalize L in WORK(IL)
                   1409: *              (CWorkspace: need M*M+3*M, prefer M*M+2*M+2*M*NB)
                   1410: *              (RWorkspace: need M)
                   1411: *
                   1412:                CALL ZGEBRD( M, M, WORK( IL ), LDWRKL, S, RWORK( IE ),
                   1413:      $                      WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
                   1414:      $                      LWORK-NWORK+1, IERR )
                   1415: *
                   1416: *              Perform bidiagonal SVD, computing left singular vectors
                   1417: *              of bidiagonal matrix in RWORK(IRU) and computing right
                   1418: *              singular vectors of bidiagonal matrix in RWORK(IRVT)
                   1419: *              (CWorkspace: need 0)
                   1420: *              (RWorkspace: need BDSPAC)
                   1421: *
                   1422:                IRU = IE + M
                   1423:                IRVT = IRU + M*M
                   1424:                NRWORK = IRVT + M*M
                   1425:                CALL DBDSDC( 'U', 'I', M, S, RWORK( IE ), RWORK( IRU ),
                   1426:      $                      M, RWORK( IRVT ), M, DUM, IDUM,
                   1427:      $                      RWORK( NRWORK ), IWORK, INFO )
                   1428: *
                   1429: *              Copy real matrix RWORK(IRU) to complex matrix U
                   1430: *              Overwrite U by left singular vectors of L
                   1431: *              (CWorkspace: need M*M+3*M, prefer M*M+2*M+M*NB)
                   1432: *              (RWorkspace: 0)
                   1433: *
                   1434:                CALL ZLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
                   1435:                CALL ZUNMBR( 'Q', 'L', 'N', M, M, M, WORK( IL ), LDWRKL,
                   1436:      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
                   1437:      $                      LWORK-NWORK+1, IERR )
                   1438: *
                   1439: *              Copy real matrix RWORK(IRVT) to complex matrix VT
                   1440: *              Overwrite VT by left singular vectors of L
                   1441: *              (CWorkspace: need M*M+3*M, prefer M*M+2*M+M*NB)
                   1442: *              (RWorkspace: 0)
                   1443: *
                   1444:                CALL ZLACP2( 'F', M, M, RWORK( IRVT ), M, VT, LDVT )
                   1445:                CALL ZUNMBR( 'P', 'R', 'C', M, M, M, WORK( IL ), LDWRKL,
                   1446:      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
                   1447:      $                      LWORK-NWORK+1, IERR )
                   1448: *
                   1449: *              Copy VT to WORK(IL), multiply right singular vectors of L
                   1450: *              in WORK(IL) by Q in A, storing result in VT
                   1451: *              (CWorkspace: need M*M)
                   1452: *              (RWorkspace: 0)
                   1453: *
                   1454:                CALL ZLACPY( 'F', M, M, VT, LDVT, WORK( IL ), LDWRKL )
                   1455:                CALL ZGEMM( 'N', 'N', M, N, M, CONE, WORK( IL ), LDWRKL,
                   1456:      $                     A, LDA, CZERO, VT, LDVT )
                   1457: *
                   1458:             ELSE IF( WNTQA ) THEN
                   1459: *
                   1460: *              Path 9t (N much larger than M, JOBZ='A')
                   1461: *              N right singular vectors to be computed in VT and
                   1462: *              M left singular vectors to be computed in U
                   1463: *
                   1464:                IVT = 1
                   1465: *
                   1466: *              WORK(IVT) is M by M
                   1467: *
                   1468:                LDWKVT = M
                   1469:                ITAU = IVT + LDWKVT*M
                   1470:                NWORK = ITAU + M
                   1471: *
                   1472: *              Compute A=L*Q, copying result to VT
                   1473: *              (CWorkspace: need 2*M, prefer M+M*NB)
                   1474: *              (RWorkspace: 0)
                   1475: *
                   1476:                CALL ZGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
                   1477:      $                      LWORK-NWORK+1, IERR )
                   1478:                CALL ZLACPY( 'U', M, N, A, LDA, VT, LDVT )
                   1479: *
                   1480: *              Generate Q in VT
                   1481: *              (CWorkspace: need M+N, prefer M+N*NB)
                   1482: *              (RWorkspace: 0)
                   1483: *
                   1484:                CALL ZUNGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
                   1485:      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                   1486: *
                   1487: *              Produce L in A, zeroing out above it
                   1488: *
                   1489:                CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO, A( 1, 2 ),
                   1490:      $                      LDA )
                   1491:                IE = 1
                   1492:                ITAUQ = ITAU
                   1493:                ITAUP = ITAUQ + M
                   1494:                NWORK = ITAUP + M
                   1495: *
                   1496: *              Bidiagonalize L in A
                   1497: *              (CWorkspace: need M*M+3*M, prefer M*M+2*M+2*M*NB)
                   1498: *              (RWorkspace: need M)
                   1499: *
                   1500:                CALL ZGEBRD( M, M, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
                   1501:      $                      WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
                   1502:      $                      IERR )
                   1503: *
                   1504: *              Perform bidiagonal SVD, computing left singular vectors
                   1505: *              of bidiagonal matrix in RWORK(IRU) and computing right
                   1506: *              singular vectors of bidiagonal matrix in RWORK(IRVT)
                   1507: *              (CWorkspace: need 0)
                   1508: *              (RWorkspace: need BDSPAC)
                   1509: *
                   1510:                IRU = IE + M
                   1511:                IRVT = IRU + M*M
                   1512:                NRWORK = IRVT + M*M
                   1513:                CALL DBDSDC( 'U', 'I', M, S, RWORK( IE ), RWORK( IRU ),
                   1514:      $                      M, RWORK( IRVT ), M, DUM, IDUM,
                   1515:      $                      RWORK( NRWORK ), IWORK, INFO )
                   1516: *
                   1517: *              Copy real matrix RWORK(IRU) to complex matrix U
                   1518: *              Overwrite U by left singular vectors of L
                   1519: *              (CWorkspace: need 3*M, prefer 2*M+M*NB)
                   1520: *              (RWorkspace: 0)
                   1521: *
                   1522:                CALL ZLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
                   1523:                CALL ZUNMBR( 'Q', 'L', 'N', M, M, M, A, LDA,
                   1524:      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
                   1525:      $                      LWORK-NWORK+1, IERR )
                   1526: *
                   1527: *              Copy real matrix RWORK(IRVT) to complex matrix WORK(IVT)
                   1528: *              Overwrite WORK(IVT) by right singular vectors of L
                   1529: *              (CWorkspace: need M*M+3*M, prefer M*M+2*M+M*NB)
                   1530: *              (RWorkspace: 0)
                   1531: *
                   1532:                CALL ZLACP2( 'F', M, M, RWORK( IRVT ), M, WORK( IVT ),
                   1533:      $                      LDWKVT )
                   1534:                CALL ZUNMBR( 'P', 'R', 'C', M, M, M, A, LDA,
                   1535:      $                      WORK( ITAUP ), WORK( IVT ), LDWKVT,
                   1536:      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                   1537: *
                   1538: *              Multiply right singular vectors of L in WORK(IVT) by
                   1539: *              Q in VT, storing result in A
                   1540: *              (CWorkspace: need M*M)
                   1541: *              (RWorkspace: 0)
                   1542: *
                   1543:                CALL ZGEMM( 'N', 'N', M, N, M, CONE, WORK( IVT ), LDWKVT,
                   1544:      $                     VT, LDVT, CZERO, A, LDA )
                   1545: *
                   1546: *              Copy right singular vectors of A from A to VT
                   1547: *
                   1548:                CALL ZLACPY( 'F', M, N, A, LDA, VT, LDVT )
                   1549: *
                   1550:             END IF
                   1551: *
                   1552:          ELSE IF( N.GE.MNTHR2 ) THEN
                   1553: *
                   1554: *           MNTHR2 <= N < MNTHR1
                   1555: *
                   1556: *           Path 5t (N much larger than M, but not as much as MNTHR1)
                   1557: *           Reduce to bidiagonal form without QR decomposition, use
                   1558: *           ZUNGBR and matrix multiplication to compute singular vectors
                   1559: *
                   1560: *
                   1561:             IE = 1
                   1562:             NRWORK = IE + M
                   1563:             ITAUQ = 1
                   1564:             ITAUP = ITAUQ + M
                   1565:             NWORK = ITAUP + M
                   1566: *
                   1567: *           Bidiagonalize A
                   1568: *           (CWorkspace: need 2*M+N, prefer 2*M+(M+N)*NB)
                   1569: *           (RWorkspace: M)
                   1570: *
                   1571:             CALL ZGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
                   1572:      $                   WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
                   1573:      $                   IERR )
                   1574: *
                   1575:             IF( WNTQN ) THEN
                   1576: *
                   1577: *              Compute singular values only
                   1578: *              (Cworkspace: 0)
                   1579: *              (Rworkspace: need BDSPAN)
                   1580: *
                   1581:                CALL DBDSDC( 'L', 'N', M, S, RWORK( IE ), DUM, 1, DUM, 1,
                   1582:      $                      DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
                   1583:             ELSE IF( WNTQO ) THEN
                   1584:                IRVT = NRWORK
                   1585:                IRU = IRVT + M*M
                   1586:                NRWORK = IRU + M*M
                   1587:                IVT = NWORK
                   1588: *
                   1589: *              Copy A to U, generate Q
                   1590: *              (Cworkspace: need 2*M, prefer M+M*NB)
                   1591: *              (Rworkspace: 0)
                   1592: *
                   1593:                CALL ZLACPY( 'L', M, M, A, LDA, U, LDU )
                   1594:                CALL ZUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
                   1595:      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                   1596: *
                   1597: *              Generate P**H in A
                   1598: *              (Cworkspace: need 2*M, prefer M+M*NB)
                   1599: *              (Rworkspace: 0)
                   1600: *
                   1601:                CALL ZUNGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
                   1602:      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                   1603: *
                   1604:                LDWKVT = M
                   1605:                IF( LWORK.GE.M*N+3*M ) THEN
                   1606: *
                   1607: *                 WORK( IVT ) is M by N
                   1608: *
                   1609:                   NWORK = IVT + LDWKVT*N
                   1610:                   CHUNK = N
                   1611:                ELSE
                   1612: *
                   1613: *                 WORK( IVT ) is M by CHUNK
                   1614: *
                   1615:                   CHUNK = ( LWORK-3*M ) / M
                   1616:                   NWORK = IVT + LDWKVT*CHUNK
                   1617:                END IF
                   1618: *
                   1619: *              Perform bidiagonal SVD, computing left singular vectors
                   1620: *              of bidiagonal matrix in RWORK(IRU) and computing right
                   1621: *              singular vectors of bidiagonal matrix in RWORK(IRVT)
                   1622: *              (CWorkspace: need 0)
                   1623: *              (RWorkspace: need BDSPAC)
                   1624: *
                   1625:                CALL DBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
                   1626:      $                      M, RWORK( IRVT ), M, DUM, IDUM,
                   1627:      $                      RWORK( NRWORK ), IWORK, INFO )
                   1628: *
                   1629: *              Multiply Q in U by real matrix RWORK(IRVT)
                   1630: *              storing the result in WORK(IVT), copying to U
                   1631: *              (Cworkspace: need 0)
                   1632: *              (Rworkspace: need 2*M*M)
                   1633: *
                   1634:                CALL ZLACRM( M, M, U, LDU, RWORK( IRU ), M, WORK( IVT ),
                   1635:      $                      LDWKVT, RWORK( NRWORK ) )
                   1636:                CALL ZLACPY( 'F', M, M, WORK( IVT ), LDWKVT, U, LDU )
                   1637: *
                   1638: *              Multiply RWORK(IRVT) by P**H in A, storing the
                   1639: *              result in WORK(IVT), copying to A
                   1640: *              (CWorkspace: need M*M, prefer M*N)
                   1641: *              (Rworkspace: need 2*M*M, prefer 2*M*N)
                   1642: *
                   1643:                NRWORK = IRU
                   1644:                DO 50 I = 1, N, CHUNK
                   1645:                   BLK = MIN( N-I+1, CHUNK )
                   1646:                   CALL ZLARCM( M, BLK, RWORK( IRVT ), M, A( 1, I ), LDA,
                   1647:      $                         WORK( IVT ), LDWKVT, RWORK( NRWORK ) )
                   1648:                   CALL ZLACPY( 'F', M, BLK, WORK( IVT ), LDWKVT,
                   1649:      $                         A( 1, I ), LDA )
                   1650:    50          CONTINUE
                   1651:             ELSE IF( WNTQS ) THEN
                   1652: *
                   1653: *              Copy A to U, generate Q
                   1654: *              (Cworkspace: need 2*M, prefer M+M*NB)
                   1655: *              (Rworkspace: 0)
                   1656: *
                   1657:                CALL ZLACPY( 'L', M, M, A, LDA, U, LDU )
                   1658:                CALL ZUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
                   1659:      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                   1660: *
                   1661: *              Copy A to VT, generate P**H
                   1662: *              (Cworkspace: need 2*M, prefer M+M*NB)
                   1663: *              (Rworkspace: 0)
                   1664: *
                   1665:                CALL ZLACPY( 'U', M, N, A, LDA, VT, LDVT )
                   1666:                CALL ZUNGBR( 'P', M, N, M, VT, LDVT, WORK( ITAUP ),
                   1667:      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                   1668: *
                   1669: *              Perform bidiagonal SVD, computing left singular vectors
                   1670: *              of bidiagonal matrix in RWORK(IRU) and computing right
                   1671: *              singular vectors of bidiagonal matrix in RWORK(IRVT)
                   1672: *              (CWorkspace: need 0)
                   1673: *              (RWorkspace: need BDSPAC)
                   1674: *
                   1675:                IRVT = NRWORK
                   1676:                IRU = IRVT + M*M
                   1677:                NRWORK = IRU + M*M
                   1678:                CALL DBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
                   1679:      $                      M, RWORK( IRVT ), M, DUM, IDUM,
                   1680:      $                      RWORK( NRWORK ), IWORK, INFO )
                   1681: *
                   1682: *              Multiply Q in U by real matrix RWORK(IRU), storing the
                   1683: *              result in A, copying to U
                   1684: *              (CWorkspace: need 0)
                   1685: *              (Rworkspace: need 3*M*M)
                   1686: *
                   1687:                CALL ZLACRM( M, M, U, LDU, RWORK( IRU ), M, A, LDA,
                   1688:      $                      RWORK( NRWORK ) )
                   1689:                CALL ZLACPY( 'F', M, M, A, LDA, U, LDU )
                   1690: *
                   1691: *              Multiply real matrix RWORK(IRVT) by P**H in VT,
                   1692: *              storing the result in A, copying to VT
                   1693: *              (Cworkspace: need 0)
                   1694: *              (Rworkspace: need M*M+2*M*N)
                   1695: *
                   1696:                NRWORK = IRU
                   1697:                CALL ZLARCM( M, N, RWORK( IRVT ), M, VT, LDVT, A, LDA,
                   1698:      $                      RWORK( NRWORK ) )
                   1699:                CALL ZLACPY( 'F', M, N, A, LDA, VT, LDVT )
                   1700:             ELSE
                   1701: *
                   1702: *              Copy A to U, generate Q
                   1703: *              (Cworkspace: need 2*M, prefer M+M*NB)
                   1704: *              (Rworkspace: 0)
                   1705: *
                   1706:                CALL ZLACPY( 'L', M, M, A, LDA, U, LDU )
                   1707:                CALL ZUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
                   1708:      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                   1709: *
                   1710: *              Copy A to VT, generate P**H
                   1711: *              (Cworkspace: need 2*M, prefer M+M*NB)
                   1712: *              (Rworkspace: 0)
                   1713: *
                   1714:                CALL ZLACPY( 'U', M, N, A, LDA, VT, LDVT )
                   1715:                CALL ZUNGBR( 'P', N, N, M, VT, LDVT, WORK( ITAUP ),
                   1716:      $                      WORK( NWORK ), LWORK-NWORK+1, IERR )
                   1717: *
                   1718: *              Perform bidiagonal SVD, computing left singular vectors
                   1719: *              of bidiagonal matrix in RWORK(IRU) and computing right
                   1720: *              singular vectors of bidiagonal matrix in RWORK(IRVT)
                   1721: *              (CWorkspace: need 0)
                   1722: *              (RWorkspace: need BDSPAC)
                   1723: *
                   1724:                IRVT = NRWORK
                   1725:                IRU = IRVT + M*M
                   1726:                NRWORK = IRU + M*M
                   1727:                CALL DBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
                   1728:      $                      M, RWORK( IRVT ), M, DUM, IDUM,
                   1729:      $                      RWORK( NRWORK ), IWORK, INFO )
                   1730: *
                   1731: *              Multiply Q in U by real matrix RWORK(IRU), storing the
                   1732: *              result in A, copying to U
                   1733: *              (CWorkspace: need 0)
                   1734: *              (Rworkspace: need 3*M*M)
                   1735: *
                   1736:                CALL ZLACRM( M, M, U, LDU, RWORK( IRU ), M, A, LDA,
                   1737:      $                      RWORK( NRWORK ) )
                   1738:                CALL ZLACPY( 'F', M, M, A, LDA, U, LDU )
                   1739: *
                   1740: *              Multiply real matrix RWORK(IRVT) by P**H in VT,
                   1741: *              storing the result in A, copying to VT
                   1742: *              (Cworkspace: need 0)
                   1743: *              (Rworkspace: need M*M+2*M*N)
                   1744: *
                   1745:                CALL ZLARCM( M, N, RWORK( IRVT ), M, VT, LDVT, A, LDA,
                   1746:      $                      RWORK( NRWORK ) )
                   1747:                CALL ZLACPY( 'F', M, N, A, LDA, VT, LDVT )
                   1748:             END IF
                   1749: *
                   1750:          ELSE
                   1751: *
                   1752: *           N .LT. MNTHR2
                   1753: *
                   1754: *           Path 6t (N greater than M, but not much larger)
                   1755: *           Reduce to bidiagonal form without LQ decomposition
                   1756: *           Use ZUNMBR to compute singular vectors
                   1757: *
                   1758:             IE = 1
                   1759:             NRWORK = IE + M
                   1760:             ITAUQ = 1
                   1761:             ITAUP = ITAUQ + M
                   1762:             NWORK = ITAUP + M
                   1763: *
                   1764: *           Bidiagonalize A
                   1765: *           (CWorkspace: need 2*M+N, prefer 2*M+(M+N)*NB)
                   1766: *           (RWorkspace: M)
                   1767: *
                   1768:             CALL ZGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
                   1769:      $                   WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
                   1770:      $                   IERR )
                   1771:             IF( WNTQN ) THEN
                   1772: *
                   1773: *              Compute singular values only
                   1774: *              (Cworkspace: 0)
                   1775: *              (Rworkspace: need BDSPAN)
                   1776: *
                   1777:                CALL DBDSDC( 'L', 'N', M, S, RWORK( IE ), DUM, 1, DUM, 1,
                   1778:      $                      DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
                   1779:             ELSE IF( WNTQO ) THEN
                   1780:                LDWKVT = M
                   1781:                IVT = NWORK
                   1782:                IF( LWORK.GE.M*N+3*M ) THEN
                   1783: *
                   1784: *                 WORK( IVT ) is M by N
                   1785: *
                   1786:                   CALL ZLASET( 'F', M, N, CZERO, CZERO, WORK( IVT ),
                   1787:      $                         LDWKVT )
                   1788:                   NWORK = IVT + LDWKVT*N
                   1789:                ELSE
                   1790: *
                   1791: *                 WORK( IVT ) is M by CHUNK
                   1792: *
                   1793:                   CHUNK = ( LWORK-3*M ) / M
                   1794:                   NWORK = IVT + LDWKVT*CHUNK
                   1795:                END IF
                   1796: *
                   1797: *              Perform bidiagonal SVD, computing left singular vectors
                   1798: *              of bidiagonal matrix in RWORK(IRU) and computing right
                   1799: *              singular vectors of bidiagonal matrix in RWORK(IRVT)
                   1800: *              (CWorkspace: need 0)
                   1801: *              (RWorkspace: need BDSPAC)
                   1802: *
                   1803:                IRVT = NRWORK
                   1804:                IRU = IRVT + M*M
                   1805:                NRWORK = IRU + M*M
                   1806:                CALL DBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
                   1807:      $                      M, RWORK( IRVT ), M, DUM, IDUM,
                   1808:      $                      RWORK( NRWORK ), IWORK, INFO )
                   1809: *
                   1810: *              Copy real matrix RWORK(IRU) to complex matrix U
                   1811: *              Overwrite U by left singular vectors of A
                   1812: *              (Cworkspace: need 2*M, prefer M+M*NB)
                   1813: *              (Rworkspace: need 0)
                   1814: *
                   1815:                CALL ZLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
                   1816:                CALL ZUNMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
                   1817:      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
                   1818:      $                      LWORK-NWORK+1, IERR )
                   1819: *
                   1820:                IF( LWORK.GE.M*N+3*M ) THEN
                   1821: *
                   1822: *              Copy real matrix RWORK(IRVT) to complex matrix WORK(IVT)
                   1823: *              Overwrite WORK(IVT) by right singular vectors of A,
                   1824: *              copying to A
                   1825: *              (Cworkspace: need M*N+2*M, prefer M*N+M+M*NB)
                   1826: *              (Rworkspace: need 0)
                   1827: *
                   1828:                   CALL ZLACP2( 'F', M, M, RWORK( IRVT ), M, WORK( IVT ),
                   1829:      $                         LDWKVT )
                   1830:                   CALL ZUNMBR( 'P', 'R', 'C', M, N, M, A, LDA,
                   1831:      $                         WORK( ITAUP ), WORK( IVT ), LDWKVT,
                   1832:      $                         WORK( NWORK ), LWORK-NWORK+1, IERR )
                   1833:                   CALL ZLACPY( 'F', M, N, WORK( IVT ), LDWKVT, A, LDA )
                   1834:                ELSE
                   1835: *
                   1836: *                 Generate P**H in A
                   1837: *                 (Cworkspace: need 2*M, prefer M+M*NB)
                   1838: *                 (Rworkspace: need 0)
                   1839: *
                   1840:                   CALL ZUNGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
                   1841:      $                         WORK( NWORK ), LWORK-NWORK+1, IERR )
                   1842: *
                   1843: *                 Multiply Q in A by real matrix RWORK(IRU), storing the
                   1844: *                 result in WORK(IU), copying to A
                   1845: *                 (CWorkspace: need M*M, prefer M*N)
                   1846: *                 (Rworkspace: need 3*M*M, prefer M*M+2*M*N)
                   1847: *
                   1848:                   NRWORK = IRU
                   1849:                   DO 60 I = 1, N, CHUNK
                   1850:                      BLK = MIN( N-I+1, CHUNK )
                   1851:                      CALL ZLARCM( M, BLK, RWORK( IRVT ), M, A( 1, I ),
                   1852:      $                            LDA, WORK( IVT ), LDWKVT,
                   1853:      $                            RWORK( NRWORK ) )
                   1854:                      CALL ZLACPY( 'F', M, BLK, WORK( IVT ), LDWKVT,
                   1855:      $                            A( 1, I ), LDA )
                   1856:    60             CONTINUE
                   1857:                END IF
                   1858:             ELSE IF( WNTQS ) THEN
                   1859: *
                   1860: *              Perform bidiagonal SVD, computing left singular vectors
                   1861: *              of bidiagonal matrix in RWORK(IRU) and computing right
                   1862: *              singular vectors of bidiagonal matrix in RWORK(IRVT)
                   1863: *              (CWorkspace: need 0)
                   1864: *              (RWorkspace: need BDSPAC)
                   1865: *
                   1866:                IRVT = NRWORK
                   1867:                IRU = IRVT + M*M
                   1868:                NRWORK = IRU + M*M
                   1869:                CALL DBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
                   1870:      $                      M, RWORK( IRVT ), M, DUM, IDUM,
                   1871:      $                      RWORK( NRWORK ), IWORK, INFO )
                   1872: *
                   1873: *              Copy real matrix RWORK(IRU) to complex matrix U
                   1874: *              Overwrite U by left singular vectors of A
                   1875: *              (CWorkspace: need 3*M, prefer 2*M+M*NB)
                   1876: *              (RWorkspace: M*M)
                   1877: *
                   1878:                CALL ZLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
                   1879:                CALL ZUNMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
                   1880:      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
                   1881:      $                      LWORK-NWORK+1, IERR )
                   1882: *
                   1883: *              Copy real matrix RWORK(IRVT) to complex matrix VT
                   1884: *              Overwrite VT by right singular vectors of A
                   1885: *              (CWorkspace: need 3*M, prefer 2*M+M*NB)
                   1886: *              (RWorkspace: M*M)
                   1887: *
                   1888:                CALL ZLASET( 'F', M, N, CZERO, CZERO, VT, LDVT )
                   1889:                CALL ZLACP2( 'F', M, M, RWORK( IRVT ), M, VT, LDVT )
                   1890:                CALL ZUNMBR( 'P', 'R', 'C', M, N, M, A, LDA,
                   1891:      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
                   1892:      $                      LWORK-NWORK+1, IERR )
                   1893:             ELSE
                   1894: *
                   1895: *              Perform bidiagonal SVD, computing left singular vectors
                   1896: *              of bidiagonal matrix in RWORK(IRU) and computing right
                   1897: *              singular vectors of bidiagonal matrix in RWORK(IRVT)
                   1898: *              (CWorkspace: need 0)
                   1899: *              (RWorkspace: need BDSPAC)
                   1900: *
                   1901:                IRVT = NRWORK
                   1902:                IRU = IRVT + M*M
                   1903:                NRWORK = IRU + M*M
                   1904: *
                   1905:                CALL DBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
                   1906:      $                      M, RWORK( IRVT ), M, DUM, IDUM,
                   1907:      $                      RWORK( NRWORK ), IWORK, INFO )
                   1908: *
                   1909: *              Copy real matrix RWORK(IRU) to complex matrix U
                   1910: *              Overwrite U by left singular vectors of A
                   1911: *              (CWorkspace: need 3*M, prefer 2*M+M*NB)
                   1912: *              (RWorkspace: M*M)
                   1913: *
                   1914:                CALL ZLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
                   1915:                CALL ZUNMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
                   1916:      $                      WORK( ITAUQ ), U, LDU, WORK( NWORK ),
                   1917:      $                      LWORK-NWORK+1, IERR )
                   1918: *
                   1919: *              Set all of VT to identity matrix
                   1920: *
                   1921:                CALL ZLASET( 'F', N, N, CZERO, CONE, VT, LDVT )
                   1922: *
                   1923: *              Copy real matrix RWORK(IRVT) to complex matrix VT
                   1924: *              Overwrite VT by right singular vectors of A
                   1925: *              (CWorkspace: need 2*M+N, prefer 2*M+N*NB)
                   1926: *              (RWorkspace: M*M)
                   1927: *
                   1928:                CALL ZLACP2( 'F', M, M, RWORK( IRVT ), M, VT, LDVT )
                   1929:                CALL ZUNMBR( 'P', 'R', 'C', N, N, M, A, LDA,
                   1930:      $                      WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
                   1931:      $                      LWORK-NWORK+1, IERR )
                   1932:             END IF
                   1933: *
                   1934:          END IF
                   1935: *
                   1936:       END IF
                   1937: *
                   1938: *     Undo scaling if necessary
                   1939: *
                   1940:       IF( ISCL.EQ.1 ) THEN
                   1941:          IF( ANRM.GT.BIGNUM )
                   1942:      $      CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,
                   1943:      $                   IERR )
                   1944:          IF( INFO.NE.0 .AND. ANRM.GT.BIGNUM )
                   1945:      $      CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN-1, 1,
                   1946:      $                   RWORK( IE ), MINMN, IERR )
                   1947:          IF( ANRM.LT.SMLNUM )
                   1948:      $      CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,
                   1949:      $                   IERR )
                   1950:          IF( INFO.NE.0 .AND. ANRM.LT.SMLNUM )
                   1951:      $      CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN-1, 1,
                   1952:      $                   RWORK( IE ), MINMN, IERR )
                   1953:       END IF
                   1954: *
                   1955: *     Return optimal workspace in WORK(1)
                   1956: *
                   1957:       WORK( 1 ) = MAXWRK
                   1958: *
                   1959:       RETURN
                   1960: *
                   1961: *     End of ZGESDD
                   1962: *
                   1963:       END

CVSweb interface <joel.bertrand@systella.fr>