LAPACK 3.3.0

dgesvd.f

Go to the documentation of this file.
00001       SUBROUTINE DGESVD( JOBU, JOBVT, M, N, A, LDA, S, U, LDU, VT, LDVT,
00002      $                   WORK, LWORK, INFO )
00003 *
00004 *  -- LAPACK driver routine (version 3.2) --
00005 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
00006 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
00007 *     November 2006
00008 *
00009 *     .. Scalar Arguments ..
00010       CHARACTER          JOBU, JOBVT
00011       INTEGER            INFO, LDA, LDU, LDVT, LWORK, M, N
00012 *     ..
00013 *     .. Array Arguments ..
00014       DOUBLE PRECISION   A( LDA, * ), S( * ), U( LDU, * ),
00015      $                   VT( LDVT, * ), WORK( * )
00016 *     ..
00017 *
00018 *  Purpose
00019 *  =======
00020 *
00021 *  DGESVD computes the singular value decomposition (SVD) of a real
00022 *  M-by-N matrix A, optionally computing the left and/or right singular
00023 *  vectors. The SVD is written
00024 *
00025 *       A = U * SIGMA * transpose(V)
00026 *
00027 *  where SIGMA is an M-by-N matrix which is zero except for its
00028 *  min(m,n) diagonal elements, U is an M-by-M orthogonal matrix, and
00029 *  V is an N-by-N orthogonal matrix.  The diagonal elements of SIGMA
00030 *  are the singular values of A; they are real and non-negative, and
00031 *  are returned in descending order.  The first min(m,n) columns of
00032 *  U and V are the left and right singular vectors of A.
00033 *
00034 *  Note that the routine returns V**T, not V.
00035 *
00036 *  Arguments
00037 *  =========
00038 *
00039 *  JOBU    (input) CHARACTER*1
00040 *          Specifies options for computing all or part of the matrix U:
00041 *          = 'A':  all M columns of U are returned in array U:
00042 *          = 'S':  the first min(m,n) columns of U (the left singular
00043 *                  vectors) are returned in the array U;
00044 *          = 'O':  the first min(m,n) columns of U (the left singular
00045 *                  vectors) are overwritten on the array A;
00046 *          = 'N':  no columns of U (no left singular vectors) are
00047 *                  computed.
00048 *
00049 *  JOBVT   (input) CHARACTER*1
00050 *          Specifies options for computing all or part of the matrix
00051 *          V**T:
00052 *          = 'A':  all N rows of V**T are returned in the array VT;
00053 *          = 'S':  the first min(m,n) rows of V**T (the right singular
00054 *                  vectors) are returned in the array VT;
00055 *          = 'O':  the first min(m,n) rows of V**T (the right singular
00056 *                  vectors) are overwritten on the array A;
00057 *          = 'N':  no rows of V**T (no right singular vectors) are
00058 *                  computed.
00059 *
00060 *          JOBVT and JOBU cannot both be 'O'.
00061 *
00062 *  M       (input) INTEGER
00063 *          The number of rows of the input matrix A.  M >= 0.
00064 *
00065 *  N       (input) INTEGER
00066 *          The number of columns of the input matrix A.  N >= 0.
00067 *
00068 *  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N)
00069 *          On entry, the M-by-N matrix A.
00070 *          On exit,
00071 *          if JOBU = 'O',  A is overwritten with the first min(m,n)
00072 *                          columns of U (the left singular vectors,
00073 *                          stored columnwise);
00074 *          if JOBVT = 'O', A is overwritten with the first min(m,n)
00075 *                          rows of V**T (the right singular vectors,
00076 *                          stored rowwise);
00077 *          if JOBU .ne. 'O' and JOBVT .ne. 'O', the contents of A
00078 *                          are destroyed.
00079 *
00080 *  LDA     (input) INTEGER
00081 *          The leading dimension of the array A.  LDA >= max(1,M).
00082 *
00083 *  S       (output) DOUBLE PRECISION array, dimension (min(M,N))
00084 *          The singular values of A, sorted so that S(i) >= S(i+1).
00085 *
00086 *  U       (output) DOUBLE PRECISION array, dimension (LDU,UCOL)
00087 *          (LDU,M) if JOBU = 'A' or (LDU,min(M,N)) if JOBU = 'S'.
00088 *          If JOBU = 'A', U contains the M-by-M orthogonal matrix U;
00089 *          if JOBU = 'S', U contains the first min(m,n) columns of U
00090 *          (the left singular vectors, stored columnwise);
00091 *          if JOBU = 'N' or 'O', U is not referenced.
00092 *
00093 *  LDU     (input) INTEGER
00094 *          The leading dimension of the array U.  LDU >= 1; if
00095 *          JOBU = 'S' or 'A', LDU >= M.
00096 *
00097 *  VT      (output) DOUBLE PRECISION array, dimension (LDVT,N)
00098 *          If JOBVT = 'A', VT contains the N-by-N orthogonal matrix
00099 *          V**T;
00100 *          if JOBVT = 'S', VT contains the first min(m,n) rows of
00101 *          V**T (the right singular vectors, stored rowwise);
00102 *          if JOBVT = 'N' or 'O', VT is not referenced.
00103 *
00104 *  LDVT    (input) INTEGER
00105 *          The leading dimension of the array VT.  LDVT >= 1; if
00106 *          JOBVT = 'A', LDVT >= N; if JOBVT = 'S', LDVT >= min(M,N).
00107 *
00108 *  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK))
00109 *          On exit, if INFO = 0, WORK(1) returns the optimal LWORK;
00110 *          if INFO > 0, WORK(2:MIN(M,N)) contains the unconverged
00111 *          superdiagonal elements of an upper bidiagonal matrix B
00112 *          whose diagonal is in S (not necessarily sorted). B
00113 *          satisfies A = U * B * VT, so it has the same singular values
00114 *          as A, and singular vectors related by U and VT.
00115 *
00116 *  LWORK   (input) INTEGER
00117 *          The dimension of the array WORK.
00118 *          LWORK >= MAX(1,3*MIN(M,N)+MAX(M,N),5*MIN(M,N)).
00119 *          For good performance, LWORK should generally be larger.
00120 *
00121 *          If LWORK = -1, then a workspace query is assumed; the routine
00122 *          only calculates the optimal size of the WORK array, returns
00123 *          this value as the first entry of the WORK array, and no error
00124 *          message related to LWORK is issued by XERBLA.
00125 *
00126 *  INFO    (output) INTEGER
00127 *          = 0:  successful exit.
00128 *          < 0:  if INFO = -i, the i-th argument had an illegal value.
00129 *          > 0:  if DBDSQR did not converge, INFO specifies how many
00130 *                superdiagonals of an intermediate bidiagonal form B
00131 *                did not converge to zero. See the description of WORK
00132 *                above for details.
00133 *
00134 *  =====================================================================
00135 *
00136 *     .. Parameters ..
00137       DOUBLE PRECISION   ZERO, ONE
00138       PARAMETER          ( ZERO = 0.0D0, ONE = 1.0D0 )
00139 *     ..
00140 *     .. Local Scalars ..
00141       LOGICAL            LQUERY, WNTUA, WNTUAS, WNTUN, WNTUO, WNTUS,
00142      $                   WNTVA, WNTVAS, WNTVN, WNTVO, WNTVS
00143       INTEGER            BDSPAC, BLK, CHUNK, I, IE, IERR, IR, ISCL,
00144      $                   ITAU, ITAUP, ITAUQ, IU, IWORK, LDWRKR, LDWRKU,
00145      $                   MAXWRK, MINMN, MINWRK, MNTHR, NCU, NCVT, NRU,
00146      $                   NRVT, WRKBL
00147       DOUBLE PRECISION   ANRM, BIGNUM, EPS, SMLNUM
00148 *     ..
00149 *     .. Local Arrays ..
00150       DOUBLE PRECISION   DUM( 1 )
00151 *     ..
00152 *     .. External Subroutines ..
00153       EXTERNAL           DBDSQR, DGEBRD, DGELQF, DGEMM, DGEQRF, DLACPY,
00154      $                   DLASCL, DLASET, DORGBR, DORGLQ, DORGQR, DORMBR,
00155      $                   XERBLA
00156 *     ..
00157 *     .. External Functions ..
00158       LOGICAL            LSAME
00159       INTEGER            ILAENV
00160       DOUBLE PRECISION   DLAMCH, DLANGE
00161       EXTERNAL           LSAME, ILAENV, DLAMCH, DLANGE
00162 *     ..
00163 *     .. Intrinsic Functions ..
00164       INTRINSIC          MAX, MIN, SQRT
00165 *     ..
00166 *     .. Executable Statements ..
00167 *
00168 *     Test the input arguments
00169 *
00170       INFO = 0
00171       MINMN = MIN( M, N )
00172       WNTUA = LSAME( JOBU, 'A' )
00173       WNTUS = LSAME( JOBU, 'S' )
00174       WNTUAS = WNTUA .OR. WNTUS
00175       WNTUO = LSAME( JOBU, 'O' )
00176       WNTUN = LSAME( JOBU, 'N' )
00177       WNTVA = LSAME( JOBVT, 'A' )
00178       WNTVS = LSAME( JOBVT, 'S' )
00179       WNTVAS = WNTVA .OR. WNTVS
00180       WNTVO = LSAME( JOBVT, 'O' )
00181       WNTVN = LSAME( JOBVT, 'N' )
00182       LQUERY = ( LWORK.EQ.-1 )
00183 *
00184       IF( .NOT.( WNTUA .OR. WNTUS .OR. WNTUO .OR. WNTUN ) ) THEN
00185          INFO = -1
00186       ELSE IF( .NOT.( WNTVA .OR. WNTVS .OR. WNTVO .OR. WNTVN ) .OR.
00187      $         ( WNTVO .AND. WNTUO ) ) THEN
00188          INFO = -2
00189       ELSE IF( M.LT.0 ) THEN
00190          INFO = -3
00191       ELSE IF( N.LT.0 ) THEN
00192          INFO = -4
00193       ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
00194          INFO = -6
00195       ELSE IF( LDU.LT.1 .OR. ( WNTUAS .AND. LDU.LT.M ) ) THEN
00196          INFO = -9
00197       ELSE IF( LDVT.LT.1 .OR. ( WNTVA .AND. LDVT.LT.N ) .OR.
00198      $         ( WNTVS .AND. LDVT.LT.MINMN ) ) THEN
00199          INFO = -11
00200       END IF
00201 *
00202 *     Compute workspace
00203 *      (Note: Comments in the code beginning "Workspace:" describe the
00204 *       minimal amount of workspace needed at that point in the code,
00205 *       as well as the preferred amount for good performance.
00206 *       NB refers to the optimal block size for the immediately
00207 *       following subroutine, as returned by ILAENV.)
00208 *
00209       IF( INFO.EQ.0 ) THEN
00210          MINWRK = 1
00211          MAXWRK = 1
00212          IF( M.GE.N .AND. MINMN.GT.0 ) THEN
00213 *
00214 *           Compute space needed for DBDSQR
00215 *
00216             MNTHR = ILAENV( 6, 'DGESVD', JOBU // JOBVT, M, N, 0, 0 )
00217             BDSPAC = 5*N
00218             IF( M.GE.MNTHR ) THEN
00219                IF( WNTUN ) THEN
00220 *
00221 *                 Path 1 (M much larger than N, JOBU='N')
00222 *
00223                   MAXWRK = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1,
00224      $                     -1 )
00225                   MAXWRK = MAX( MAXWRK, 3*N+2*N*
00226      $                     ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
00227                   IF( WNTVO .OR. WNTVAS )
00228      $               MAXWRK = MAX( MAXWRK, 3*N+( N-1 )*
00229      $                        ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
00230                   MAXWRK = MAX( MAXWRK, BDSPAC )
00231                   MINWRK = MAX( 4*N, BDSPAC )
00232                ELSE IF( WNTUO .AND. WNTVN ) THEN
00233 *
00234 *                 Path 2 (M much larger than N, JOBU='O', JOBVT='N')
00235 *
00236                   WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
00237                   WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
00238      $                    N, N, -1 ) )
00239                   WRKBL = MAX( WRKBL, 3*N+2*N*
00240      $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
00241                   WRKBL = MAX( WRKBL, 3*N+N*
00242      $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
00243                   WRKBL = MAX( WRKBL, BDSPAC )
00244                   MAXWRK = MAX( N*N+WRKBL, N*N+M*N+N )
00245                   MINWRK = MAX( 3*N+M, BDSPAC )
00246                ELSE IF( WNTUO .AND. WNTVAS ) THEN
00247 *
00248 *                 Path 3 (M much larger than N, JOBU='O', JOBVT='S' or
00249 *                 'A')
00250 *
00251                   WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
00252                   WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
00253      $                    N, N, -1 ) )
00254                   WRKBL = MAX( WRKBL, 3*N+2*N*
00255      $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
00256                   WRKBL = MAX( WRKBL, 3*N+N*
00257      $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
00258                   WRKBL = MAX( WRKBL, 3*N+( N-1 )*
00259      $                    ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
00260                   WRKBL = MAX( WRKBL, BDSPAC )
00261                   MAXWRK = MAX( N*N+WRKBL, N*N+M*N+N )
00262                   MINWRK = MAX( 3*N+M, BDSPAC )
00263                ELSE IF( WNTUS .AND. WNTVN ) THEN
00264 *
00265 *                 Path 4 (M much larger than N, JOBU='S', JOBVT='N')
00266 *
00267                   WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
00268                   WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
00269      $                    N, N, -1 ) )
00270                   WRKBL = MAX( WRKBL, 3*N+2*N*
00271      $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
00272                   WRKBL = MAX( WRKBL, 3*N+N*
00273      $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
00274                   WRKBL = MAX( WRKBL, BDSPAC )
00275                   MAXWRK = N*N + WRKBL
00276                   MINWRK = MAX( 3*N+M, BDSPAC )
00277                ELSE IF( WNTUS .AND. WNTVO ) THEN
00278 *
00279 *                 Path 5 (M much larger than N, JOBU='S', JOBVT='O')
00280 *
00281                   WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
00282                   WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
00283      $                    N, N, -1 ) )
00284                   WRKBL = MAX( WRKBL, 3*N+2*N*
00285      $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
00286                   WRKBL = MAX( WRKBL, 3*N+N*
00287      $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
00288                   WRKBL = MAX( WRKBL, 3*N+( N-1 )*
00289      $                    ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
00290                   WRKBL = MAX( WRKBL, BDSPAC )
00291                   MAXWRK = 2*N*N + WRKBL
00292                   MINWRK = MAX( 3*N+M, BDSPAC )
00293                ELSE IF( WNTUS .AND. WNTVAS ) THEN
00294 *
00295 *                 Path 6 (M much larger than N, JOBU='S', JOBVT='S' or
00296 *                 'A')
00297 *
00298                   WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
00299                   WRKBL = MAX( WRKBL, N+N*ILAENV( 1, 'DORGQR', ' ', M,
00300      $                    N, N, -1 ) )
00301                   WRKBL = MAX( WRKBL, 3*N+2*N*
00302      $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
00303                   WRKBL = MAX( WRKBL, 3*N+N*
00304      $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
00305                   WRKBL = MAX( WRKBL, 3*N+( N-1 )*
00306      $                    ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
00307                   WRKBL = MAX( WRKBL, BDSPAC )
00308                   MAXWRK = N*N + WRKBL
00309                   MINWRK = MAX( 3*N+M, BDSPAC )
00310                ELSE IF( WNTUA .AND. WNTVN ) THEN
00311 *
00312 *                 Path 7 (M much larger than N, JOBU='A', JOBVT='N')
00313 *
00314                   WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
00315                   WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'DORGQR', ' ', M,
00316      $                    M, N, -1 ) )
00317                   WRKBL = MAX( WRKBL, 3*N+2*N*
00318      $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
00319                   WRKBL = MAX( WRKBL, 3*N+N*
00320      $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
00321                   WRKBL = MAX( WRKBL, BDSPAC )
00322                   MAXWRK = N*N + WRKBL
00323                   MINWRK = MAX( 3*N+M, BDSPAC )
00324                ELSE IF( WNTUA .AND. WNTVO ) THEN
00325 *
00326 *                 Path 8 (M much larger than N, JOBU='A', JOBVT='O')
00327 *
00328                   WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
00329                   WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'DORGQR', ' ', M,
00330      $                    M, N, -1 ) )
00331                   WRKBL = MAX( WRKBL, 3*N+2*N*
00332      $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
00333                   WRKBL = MAX( WRKBL, 3*N+N*
00334      $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
00335                   WRKBL = MAX( WRKBL, 3*N+( N-1 )*
00336      $                    ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
00337                   WRKBL = MAX( WRKBL, BDSPAC )
00338                   MAXWRK = 2*N*N + WRKBL
00339                   MINWRK = MAX( 3*N+M, BDSPAC )
00340                ELSE IF( WNTUA .AND. WNTVAS ) THEN
00341 *
00342 *                 Path 9 (M much larger than N, JOBU='A', JOBVT='S' or
00343 *                 'A')
00344 *
00345                   WRKBL = N + N*ILAENV( 1, 'DGEQRF', ' ', M, N, -1, -1 )
00346                   WRKBL = MAX( WRKBL, N+M*ILAENV( 1, 'DORGQR', ' ', M,
00347      $                    M, N, -1 ) )
00348                   WRKBL = MAX( WRKBL, 3*N+2*N*
00349      $                    ILAENV( 1, 'DGEBRD', ' ', N, N, -1, -1 ) )
00350                   WRKBL = MAX( WRKBL, 3*N+N*
00351      $                    ILAENV( 1, 'DORGBR', 'Q', N, N, N, -1 ) )
00352                   WRKBL = MAX( WRKBL, 3*N+( N-1 )*
00353      $                    ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
00354                   WRKBL = MAX( WRKBL, BDSPAC )
00355                   MAXWRK = N*N + WRKBL
00356                   MINWRK = MAX( 3*N+M, BDSPAC )
00357                END IF
00358             ELSE
00359 *
00360 *              Path 10 (M at least N, but not much larger)
00361 *
00362                MAXWRK = 3*N + ( M+N )*ILAENV( 1, 'DGEBRD', ' ', M, N,
00363      $                  -1, -1 )
00364                IF( WNTUS .OR. WNTUO )
00365      $            MAXWRK = MAX( MAXWRK, 3*N+N*
00366      $                     ILAENV( 1, 'DORGBR', 'Q', M, N, N, -1 ) )
00367                IF( WNTUA )
00368      $            MAXWRK = MAX( MAXWRK, 3*N+M*
00369      $                     ILAENV( 1, 'DORGBR', 'Q', M, M, N, -1 ) )
00370                IF( .NOT.WNTVN )
00371      $            MAXWRK = MAX( MAXWRK, 3*N+( N-1 )*
00372      $                     ILAENV( 1, 'DORGBR', 'P', N, N, N, -1 ) )
00373                MAXWRK = MAX( MAXWRK, BDSPAC )
00374                MINWRK = MAX( 3*N+M, BDSPAC )
00375             END IF
00376          ELSE IF( MINMN.GT.0 ) THEN
00377 *
00378 *           Compute space needed for DBDSQR
00379 *
00380             MNTHR = ILAENV( 6, 'DGESVD', JOBU // JOBVT, M, N, 0, 0 )
00381             BDSPAC = 5*M
00382             IF( N.GE.MNTHR ) THEN
00383                IF( WNTVN ) THEN
00384 *
00385 *                 Path 1t(N much larger than M, JOBVT='N')
00386 *
00387                   MAXWRK = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1,
00388      $                     -1 )
00389                   MAXWRK = MAX( MAXWRK, 3*M+2*M*
00390      $                     ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
00391                   IF( WNTUO .OR. WNTUAS )
00392      $               MAXWRK = MAX( MAXWRK, 3*M+M*
00393      $                        ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
00394                   MAXWRK = MAX( MAXWRK, BDSPAC )
00395                   MINWRK = MAX( 4*M, BDSPAC )
00396                ELSE IF( WNTVO .AND. WNTUN ) THEN
00397 *
00398 *                 Path 2t(N much larger than M, JOBU='N', JOBVT='O')
00399 *
00400                   WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
00401                   WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
00402      $                    N, M, -1 ) )
00403                   WRKBL = MAX( WRKBL, 3*M+2*M*
00404      $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
00405                   WRKBL = MAX( WRKBL, 3*M+( M-1 )*
00406      $                    ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
00407                   WRKBL = MAX( WRKBL, BDSPAC )
00408                   MAXWRK = MAX( M*M+WRKBL, M*M+M*N+M )
00409                   MINWRK = MAX( 3*M+N, BDSPAC )
00410                ELSE IF( WNTVO .AND. WNTUAS ) THEN
00411 *
00412 *                 Path 3t(N much larger than M, JOBU='S' or 'A',
00413 *                 JOBVT='O')
00414 *
00415                   WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
00416                   WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
00417      $                    N, M, -1 ) )
00418                   WRKBL = MAX( WRKBL, 3*M+2*M*
00419      $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
00420                   WRKBL = MAX( WRKBL, 3*M+( M-1 )*
00421      $                    ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
00422                   WRKBL = MAX( WRKBL, 3*M+M*
00423      $                    ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
00424                   WRKBL = MAX( WRKBL, BDSPAC )
00425                   MAXWRK = MAX( M*M+WRKBL, M*M+M*N+M )
00426                   MINWRK = MAX( 3*M+N, BDSPAC )
00427                ELSE IF( WNTVS .AND. WNTUN ) THEN
00428 *
00429 *                 Path 4t(N much larger than M, JOBU='N', JOBVT='S')
00430 *
00431                   WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
00432                   WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
00433      $                    N, M, -1 ) )
00434                   WRKBL = MAX( WRKBL, 3*M+2*M*
00435      $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
00436                   WRKBL = MAX( WRKBL, 3*M+( M-1 )*
00437      $                    ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
00438                   WRKBL = MAX( WRKBL, BDSPAC )
00439                   MAXWRK = M*M + WRKBL
00440                   MINWRK = MAX( 3*M+N, BDSPAC )
00441                ELSE IF( WNTVS .AND. WNTUO ) THEN
00442 *
00443 *                 Path 5t(N much larger than M, JOBU='O', JOBVT='S')
00444 *
00445                   WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
00446                   WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
00447      $                    N, M, -1 ) )
00448                   WRKBL = MAX( WRKBL, 3*M+2*M*
00449      $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
00450                   WRKBL = MAX( WRKBL, 3*M+( M-1 )*
00451      $                    ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
00452                   WRKBL = MAX( WRKBL, 3*M+M*
00453      $                    ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
00454                   WRKBL = MAX( WRKBL, BDSPAC )
00455                   MAXWRK = 2*M*M + WRKBL
00456                   MINWRK = MAX( 3*M+N, BDSPAC )
00457                ELSE IF( WNTVS .AND. WNTUAS ) THEN
00458 *
00459 *                 Path 6t(N much larger than M, JOBU='S' or 'A',
00460 *                 JOBVT='S')
00461 *
00462                   WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
00463                   WRKBL = MAX( WRKBL, M+M*ILAENV( 1, 'DORGLQ', ' ', M,
00464      $                    N, M, -1 ) )
00465                   WRKBL = MAX( WRKBL, 3*M+2*M*
00466      $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
00467                   WRKBL = MAX( WRKBL, 3*M+( M-1 )*
00468      $                    ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
00469                   WRKBL = MAX( WRKBL, 3*M+M*
00470      $                    ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
00471                   WRKBL = MAX( WRKBL, BDSPAC )
00472                   MAXWRK = M*M + WRKBL
00473                   MINWRK = MAX( 3*M+N, BDSPAC )
00474                ELSE IF( WNTVA .AND. WNTUN ) THEN
00475 *
00476 *                 Path 7t(N much larger than M, JOBU='N', JOBVT='A')
00477 *
00478                   WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
00479                   WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'DORGLQ', ' ', N,
00480      $                    N, M, -1 ) )
00481                   WRKBL = MAX( WRKBL, 3*M+2*M*
00482      $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
00483                   WRKBL = MAX( WRKBL, 3*M+( M-1 )*
00484      $                    ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
00485                   WRKBL = MAX( WRKBL, BDSPAC )
00486                   MAXWRK = M*M + WRKBL
00487                   MINWRK = MAX( 3*M+N, BDSPAC )
00488                ELSE IF( WNTVA .AND. WNTUO ) THEN
00489 *
00490 *                 Path 8t(N much larger than M, JOBU='O', JOBVT='A')
00491 *
00492                   WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
00493                   WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'DORGLQ', ' ', N,
00494      $                    N, M, -1 ) )
00495                   WRKBL = MAX( WRKBL, 3*M+2*M*
00496      $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
00497                   WRKBL = MAX( WRKBL, 3*M+( M-1 )*
00498      $                    ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
00499                   WRKBL = MAX( WRKBL, 3*M+M*
00500      $                    ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
00501                   WRKBL = MAX( WRKBL, BDSPAC )
00502                   MAXWRK = 2*M*M + WRKBL
00503                   MINWRK = MAX( 3*M+N, BDSPAC )
00504                ELSE IF( WNTVA .AND. WNTUAS ) THEN
00505 *
00506 *                 Path 9t(N much larger than M, JOBU='S' or 'A',
00507 *                 JOBVT='A')
00508 *
00509                   WRKBL = M + M*ILAENV( 1, 'DGELQF', ' ', M, N, -1, -1 )
00510                   WRKBL = MAX( WRKBL, M+N*ILAENV( 1, 'DORGLQ', ' ', N,
00511      $                    N, M, -1 ) )
00512                   WRKBL = MAX( WRKBL, 3*M+2*M*
00513      $                    ILAENV( 1, 'DGEBRD', ' ', M, M, -1, -1 ) )
00514                   WRKBL = MAX( WRKBL, 3*M+( M-1 )*
00515      $                    ILAENV( 1, 'DORGBR', 'P', M, M, M, -1 ) )
00516                   WRKBL = MAX( WRKBL, 3*M+M*
00517      $                    ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
00518                   WRKBL = MAX( WRKBL, BDSPAC )
00519                   MAXWRK = M*M + WRKBL
00520                   MINWRK = MAX( 3*M+N, BDSPAC )
00521                END IF
00522             ELSE
00523 *
00524 *              Path 10t(N greater than M, but not much larger)
00525 *
00526                MAXWRK = 3*M + ( M+N )*ILAENV( 1, 'DGEBRD', ' ', M, N,
00527      $                  -1, -1 )
00528                IF( WNTVS .OR. WNTVO )
00529      $            MAXWRK = MAX( MAXWRK, 3*M+M*
00530      $                     ILAENV( 1, 'DORGBR', 'P', M, N, M, -1 ) )
00531                IF( WNTVA )
00532      $            MAXWRK = MAX( MAXWRK, 3*M+N*
00533      $                     ILAENV( 1, 'DORGBR', 'P', N, N, M, -1 ) )
00534                IF( .NOT.WNTUN )
00535      $            MAXWRK = MAX( MAXWRK, 3*M+( M-1 )*
00536      $                     ILAENV( 1, 'DORGBR', 'Q', M, M, M, -1 ) )
00537                MAXWRK = MAX( MAXWRK, BDSPAC )
00538                MINWRK = MAX( 3*M+N, BDSPAC )
00539             END IF
00540          END IF
00541          MAXWRK = MAX( MAXWRK, MINWRK )
00542          WORK( 1 ) = MAXWRK
00543 *
00544          IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
00545             INFO = -13
00546          END IF
00547       END IF
00548 *
00549       IF( INFO.NE.0 ) THEN
00550          CALL XERBLA( 'DGESVD', -INFO )
00551          RETURN
00552       ELSE IF( LQUERY ) THEN
00553          RETURN
00554       END IF
00555 *
00556 *     Quick return if possible
00557 *
00558       IF( M.EQ.0 .OR. N.EQ.0 ) THEN
00559          RETURN
00560       END IF
00561 *
00562 *     Get machine constants
00563 *
00564       EPS = DLAMCH( 'P' )
00565       SMLNUM = SQRT( DLAMCH( 'S' ) ) / EPS
00566       BIGNUM = ONE / SMLNUM
00567 *
00568 *     Scale A if max element outside range [SMLNUM,BIGNUM]
00569 *
00570       ANRM = DLANGE( 'M', M, N, A, LDA, DUM )
00571       ISCL = 0
00572       IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
00573          ISCL = 1
00574          CALL DLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, IERR )
00575       ELSE IF( ANRM.GT.BIGNUM ) THEN
00576          ISCL = 1
00577          CALL DLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, IERR )
00578       END IF
00579 *
00580       IF( M.GE.N ) THEN
00581 *
00582 *        A has at least as many rows as columns. If A has sufficiently
00583 *        more rows than columns, first reduce using the QR
00584 *        decomposition (if sufficient workspace available)
00585 *
00586          IF( M.GE.MNTHR ) THEN
00587 *
00588             IF( WNTUN ) THEN
00589 *
00590 *              Path 1 (M much larger than N, JOBU='N')
00591 *              No left singular vectors to be computed
00592 *
00593                ITAU = 1
00594                IWORK = ITAU + N
00595 *
00596 *              Compute A=Q*R
00597 *              (Workspace: need 2*N, prefer N+N*NB)
00598 *
00599                CALL DGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
00600      $                      LWORK-IWORK+1, IERR )
00601 *
00602 *              Zero out below R
00603 *
00604                CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ), LDA )
00605                IE = 1
00606                ITAUQ = IE + N
00607                ITAUP = ITAUQ + N
00608                IWORK = ITAUP + N
00609 *
00610 *              Bidiagonalize R in A
00611 *              (Workspace: need 4*N, prefer 3*N+2*N*NB)
00612 *
00613                CALL DGEBRD( N, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
00614      $                      WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
00615      $                      IERR )
00616                NCVT = 0
00617                IF( WNTVO .OR. WNTVAS ) THEN
00618 *
00619 *                 If right singular vectors desired, generate P'.
00620 *                 (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
00621 *
00622                   CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
00623      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
00624                   NCVT = N
00625                END IF
00626                IWORK = IE + N
00627 *
00628 *              Perform bidiagonal QR iteration, computing right
00629 *              singular vectors of A in A if desired
00630 *              (Workspace: need BDSPAC)
00631 *
00632                CALL DBDSQR( 'U', N, NCVT, 0, 0, S, WORK( IE ), A, LDA,
00633      $                      DUM, 1, DUM, 1, WORK( IWORK ), INFO )
00634 *
00635 *              If right singular vectors desired in VT, copy them there
00636 *
00637                IF( WNTVAS )
00638      $            CALL DLACPY( 'F', N, N, A, LDA, VT, LDVT )
00639 *
00640             ELSE IF( WNTUO .AND. WNTVN ) THEN
00641 *
00642 *              Path 2 (M much larger than N, JOBU='O', JOBVT='N')
00643 *              N left singular vectors to be overwritten on A and
00644 *              no right singular vectors to be computed
00645 *
00646                IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN
00647 *
00648 *                 Sufficient workspace for a fast algorithm
00649 *
00650                   IR = 1
00651                   IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+LDA*N ) THEN
00652 *
00653 *                    WORK(IU) is LDA by N, WORK(IR) is LDA by N
00654 *
00655                      LDWRKU = LDA
00656                      LDWRKR = LDA
00657                   ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+N*N ) THEN
00658 *
00659 *                    WORK(IU) is LDA by N, WORK(IR) is N by N
00660 *
00661                      LDWRKU = LDA
00662                      LDWRKR = N
00663                   ELSE
00664 *
00665 *                    WORK(IU) is LDWRKU by N, WORK(IR) is N by N
00666 *
00667                      LDWRKU = ( LWORK-N*N-N ) / N
00668                      LDWRKR = N
00669                   END IF
00670                   ITAU = IR + LDWRKR*N
00671                   IWORK = ITAU + N
00672 *
00673 *                 Compute A=Q*R
00674 *                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
00675 *
00676                   CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
00677      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
00678 *
00679 *                 Copy R to WORK(IR) and zero out below it
00680 *
00681                   CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )
00682                   CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, WORK( IR+1 ),
00683      $                         LDWRKR )
00684 *
00685 *                 Generate Q in A
00686 *                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
00687 *
00688                   CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
00689      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
00690                   IE = ITAU
00691                   ITAUQ = IE + N
00692                   ITAUP = ITAUQ + N
00693                   IWORK = ITAUP + N
00694 *
00695 *                 Bidiagonalize R in WORK(IR)
00696 *                 (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
00697 *
00698                   CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S, WORK( IE ),
00699      $                         WORK( ITAUQ ), WORK( ITAUP ),
00700      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
00701 *
00702 *                 Generate left vectors bidiagonalizing R
00703 *                 (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
00704 *
00705                   CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
00706      $                         WORK( ITAUQ ), WORK( IWORK ),
00707      $                         LWORK-IWORK+1, IERR )
00708                   IWORK = IE + N
00709 *
00710 *                 Perform bidiagonal QR iteration, computing left
00711 *                 singular vectors of R in WORK(IR)
00712 *                 (Workspace: need N*N+BDSPAC)
00713 *
00714                   CALL DBDSQR( 'U', N, 0, N, 0, S, WORK( IE ), DUM, 1,
00715      $                         WORK( IR ), LDWRKR, DUM, 1,
00716      $                         WORK( IWORK ), INFO )
00717                   IU = IE + N
00718 *
00719 *                 Multiply Q in A by left singular vectors of R in
00720 *                 WORK(IR), storing result in WORK(IU) and copying to A
00721 *                 (Workspace: need N*N+2*N, prefer N*N+M*N+N)
00722 *
00723                   DO 10 I = 1, M, LDWRKU
00724                      CHUNK = MIN( M-I+1, LDWRKU )
00725                      CALL DGEMM( 'N', 'N', CHUNK, N, N, ONE, A( I, 1 ),
00726      $                           LDA, WORK( IR ), LDWRKR, ZERO,
00727      $                           WORK( IU ), LDWRKU )
00728                      CALL DLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,
00729      $                            A( I, 1 ), LDA )
00730    10             CONTINUE
00731 *
00732                ELSE
00733 *
00734 *                 Insufficient workspace for a fast algorithm
00735 *
00736                   IE = 1
00737                   ITAUQ = IE + N
00738                   ITAUP = ITAUQ + N
00739                   IWORK = ITAUP + N
00740 *
00741 *                 Bidiagonalize A
00742 *                 (Workspace: need 3*N+M, prefer 3*N+(M+N)*NB)
00743 *
00744                   CALL DGEBRD( M, N, A, LDA, S, WORK( IE ),
00745      $                         WORK( ITAUQ ), WORK( ITAUP ),
00746      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
00747 *
00748 *                 Generate left vectors bidiagonalizing A
00749 *                 (Workspace: need 4*N, prefer 3*N+N*NB)
00750 *
00751                   CALL DORGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
00752      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
00753                   IWORK = IE + N
00754 *
00755 *                 Perform bidiagonal QR iteration, computing left
00756 *                 singular vectors of A in A
00757 *                 (Workspace: need BDSPAC)
00758 *
00759                   CALL DBDSQR( 'U', N, 0, M, 0, S, WORK( IE ), DUM, 1,
00760      $                         A, LDA, DUM, 1, WORK( IWORK ), INFO )
00761 *
00762                END IF
00763 *
00764             ELSE IF( WNTUO .AND. WNTVAS ) THEN
00765 *
00766 *              Path 3 (M much larger than N, JOBU='O', JOBVT='S' or 'A')
00767 *              N left singular vectors to be overwritten on A and
00768 *              N right singular vectors to be computed in VT
00769 *
00770                IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN
00771 *
00772 *                 Sufficient workspace for a fast algorithm
00773 *
00774                   IR = 1
00775                   IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+LDA*N ) THEN
00776 *
00777 *                    WORK(IU) is LDA by N and WORK(IR) is LDA by N
00778 *
00779                      LDWRKU = LDA
00780                      LDWRKR = LDA
00781                   ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+N )+N*N ) THEN
00782 *
00783 *                    WORK(IU) is LDA by N and WORK(IR) is N by N
00784 *
00785                      LDWRKU = LDA
00786                      LDWRKR = N
00787                   ELSE
00788 *
00789 *                    WORK(IU) is LDWRKU by N and WORK(IR) is N by N
00790 *
00791                      LDWRKU = ( LWORK-N*N-N ) / N
00792                      LDWRKR = N
00793                   END IF
00794                   ITAU = IR + LDWRKR*N
00795                   IWORK = ITAU + N
00796 *
00797 *                 Compute A=Q*R
00798 *                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
00799 *
00800                   CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
00801      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
00802 *
00803 *                 Copy R to VT, zeroing out below it
00804 *
00805                   CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )
00806                   IF( N.GT.1 )
00807      $               CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
00808      $                            VT( 2, 1 ), LDVT )
00809 *
00810 *                 Generate Q in A
00811 *                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
00812 *
00813                   CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
00814      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
00815                   IE = ITAU
00816                   ITAUQ = IE + N
00817                   ITAUP = ITAUQ + N
00818                   IWORK = ITAUP + N
00819 *
00820 *                 Bidiagonalize R in VT, copying result to WORK(IR)
00821 *                 (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
00822 *
00823                   CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),
00824      $                         WORK( ITAUQ ), WORK( ITAUP ),
00825      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
00826                   CALL DLACPY( 'L', N, N, VT, LDVT, WORK( IR ), LDWRKR )
00827 *
00828 *                 Generate left vectors bidiagonalizing R in WORK(IR)
00829 *                 (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
00830 *
00831                   CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
00832      $                         WORK( ITAUQ ), WORK( IWORK ),
00833      $                         LWORK-IWORK+1, IERR )
00834 *
00835 *                 Generate right vectors bidiagonalizing R in VT
00836 *                 (Workspace: need N*N+4*N-1, prefer N*N+3*N+(N-1)*NB)
00837 *
00838                   CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
00839      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
00840                   IWORK = IE + N
00841 *
00842 *                 Perform bidiagonal QR iteration, computing left
00843 *                 singular vectors of R in WORK(IR) and computing right
00844 *                 singular vectors of R in VT
00845 *                 (Workspace: need N*N+BDSPAC)
00846 *
00847                   CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ), VT, LDVT,
00848      $                         WORK( IR ), LDWRKR, DUM, 1,
00849      $                         WORK( IWORK ), INFO )
00850                   IU = IE + N
00851 *
00852 *                 Multiply Q in A by left singular vectors of R in
00853 *                 WORK(IR), storing result in WORK(IU) and copying to A
00854 *                 (Workspace: need N*N+2*N, prefer N*N+M*N+N)
00855 *
00856                   DO 20 I = 1, M, LDWRKU
00857                      CHUNK = MIN( M-I+1, LDWRKU )
00858                      CALL DGEMM( 'N', 'N', CHUNK, N, N, ONE, A( I, 1 ),
00859      $                           LDA, WORK( IR ), LDWRKR, ZERO,
00860      $                           WORK( IU ), LDWRKU )
00861                      CALL DLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,
00862      $                            A( I, 1 ), LDA )
00863    20             CONTINUE
00864 *
00865                ELSE
00866 *
00867 *                 Insufficient workspace for a fast algorithm
00868 *
00869                   ITAU = 1
00870                   IWORK = ITAU + N
00871 *
00872 *                 Compute A=Q*R
00873 *                 (Workspace: need 2*N, prefer N+N*NB)
00874 *
00875                   CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
00876      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
00877 *
00878 *                 Copy R to VT, zeroing out below it
00879 *
00880                   CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )
00881                   IF( N.GT.1 )
00882      $               CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
00883      $                            VT( 2, 1 ), LDVT )
00884 *
00885 *                 Generate Q in A
00886 *                 (Workspace: need 2*N, prefer N+N*NB)
00887 *
00888                   CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
00889      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
00890                   IE = ITAU
00891                   ITAUQ = IE + N
00892                   ITAUP = ITAUQ + N
00893                   IWORK = ITAUP + N
00894 *
00895 *                 Bidiagonalize R in VT
00896 *                 (Workspace: need 4*N, prefer 3*N+2*N*NB)
00897 *
00898                   CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),
00899      $                         WORK( ITAUQ ), WORK( ITAUP ),
00900      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
00901 *
00902 *                 Multiply Q in A by left vectors bidiagonalizing R
00903 *                 (Workspace: need 3*N+M, prefer 3*N+M*NB)
00904 *
00905                   CALL DORMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
00906      $                         WORK( ITAUQ ), A, LDA, WORK( IWORK ),
00907      $                         LWORK-IWORK+1, IERR )
00908 *
00909 *                 Generate right vectors bidiagonalizing R in VT
00910 *                 (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
00911 *
00912                   CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
00913      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
00914                   IWORK = IE + N
00915 *
00916 *                 Perform bidiagonal QR iteration, computing left
00917 *                 singular vectors of A in A and computing right
00918 *                 singular vectors of A in VT
00919 *                 (Workspace: need BDSPAC)
00920 *
00921                   CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), VT, LDVT,
00922      $                         A, LDA, DUM, 1, WORK( IWORK ), INFO )
00923 *
00924                END IF
00925 *
00926             ELSE IF( WNTUS ) THEN
00927 *
00928                IF( WNTVN ) THEN
00929 *
00930 *                 Path 4 (M much larger than N, JOBU='S', JOBVT='N')
00931 *                 N left singular vectors to be computed in U and
00932 *                 no right singular vectors to be computed
00933 *
00934                   IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN
00935 *
00936 *                    Sufficient workspace for a fast algorithm
00937 *
00938                      IR = 1
00939                      IF( LWORK.GE.WRKBL+LDA*N ) THEN
00940 *
00941 *                       WORK(IR) is LDA by N
00942 *
00943                         LDWRKR = LDA
00944                      ELSE
00945 *
00946 *                       WORK(IR) is N by N
00947 *
00948                         LDWRKR = N
00949                      END IF
00950                      ITAU = IR + LDWRKR*N
00951                      IWORK = ITAU + N
00952 *
00953 *                    Compute A=Q*R
00954 *                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
00955 *
00956                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
00957      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
00958 *
00959 *                    Copy R to WORK(IR), zeroing out below it
00960 *
00961                      CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ),
00962      $                            LDWRKR )
00963                      CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
00964      $                            WORK( IR+1 ), LDWRKR )
00965 *
00966 *                    Generate Q in A
00967 *                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
00968 *
00969                      CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
00970      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
00971                      IE = ITAU
00972                      ITAUQ = IE + N
00973                      ITAUP = ITAUQ + N
00974                      IWORK = ITAUP + N
00975 *
00976 *                    Bidiagonalize R in WORK(IR)
00977 *                    (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
00978 *
00979                      CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S,
00980      $                            WORK( IE ), WORK( ITAUQ ),
00981      $                            WORK( ITAUP ), WORK( IWORK ),
00982      $                            LWORK-IWORK+1, IERR )
00983 *
00984 *                    Generate left vectors bidiagonalizing R in WORK(IR)
00985 *                    (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
00986 *
00987                      CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
00988      $                            WORK( ITAUQ ), WORK( IWORK ),
00989      $                            LWORK-IWORK+1, IERR )
00990                      IWORK = IE + N
00991 *
00992 *                    Perform bidiagonal QR iteration, computing left
00993 *                    singular vectors of R in WORK(IR)
00994 *                    (Workspace: need N*N+BDSPAC)
00995 *
00996                      CALL DBDSQR( 'U', N, 0, N, 0, S, WORK( IE ), DUM,
00997      $                            1, WORK( IR ), LDWRKR, DUM, 1,
00998      $                            WORK( IWORK ), INFO )
00999 *
01000 *                    Multiply Q in A by left singular vectors of R in
01001 *                    WORK(IR), storing result in U
01002 *                    (Workspace: need N*N)
01003 *
01004                      CALL DGEMM( 'N', 'N', M, N, N, ONE, A, LDA,
01005      $                           WORK( IR ), LDWRKR, ZERO, U, LDU )
01006 *
01007                   ELSE
01008 *
01009 *                    Insufficient workspace for a fast algorithm
01010 *
01011                      ITAU = 1
01012                      IWORK = ITAU + N
01013 *
01014 *                    Compute A=Q*R, copying result to U
01015 *                    (Workspace: need 2*N, prefer N+N*NB)
01016 *
01017                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
01018      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01019                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
01020 *
01021 *                    Generate Q in U
01022 *                    (Workspace: need 2*N, prefer N+N*NB)
01023 *
01024                      CALL DORGQR( M, N, N, U, LDU, WORK( ITAU ),
01025      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01026                      IE = ITAU
01027                      ITAUQ = IE + N
01028                      ITAUP = ITAUQ + N
01029                      IWORK = ITAUP + N
01030 *
01031 *                    Zero out below R in A
01032 *
01033                      CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
01034      $                            LDA )
01035 *
01036 *                    Bidiagonalize R in A
01037 *                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
01038 *
01039                      CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),
01040      $                            WORK( ITAUQ ), WORK( ITAUP ),
01041      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01042 *
01043 *                    Multiply Q in U by left vectors bidiagonalizing R
01044 *                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
01045 *
01046                      CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
01047      $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
01048      $                            LWORK-IWORK+1, IERR )
01049                      IWORK = IE + N
01050 *
01051 *                    Perform bidiagonal QR iteration, computing left
01052 *                    singular vectors of A in U
01053 *                    (Workspace: need BDSPAC)
01054 *
01055                      CALL DBDSQR( 'U', N, 0, M, 0, S, WORK( IE ), DUM,
01056      $                            1, U, LDU, DUM, 1, WORK( IWORK ),
01057      $                            INFO )
01058 *
01059                   END IF
01060 *
01061                ELSE IF( WNTVO ) THEN
01062 *
01063 *                 Path 5 (M much larger than N, JOBU='S', JOBVT='O')
01064 *                 N left singular vectors to be computed in U and
01065 *                 N right singular vectors to be overwritten on A
01066 *
01067                   IF( LWORK.GE.2*N*N+MAX( 4*N, BDSPAC ) ) THEN
01068 *
01069 *                    Sufficient workspace for a fast algorithm
01070 *
01071                      IU = 1
01072                      IF( LWORK.GE.WRKBL+2*LDA*N ) THEN
01073 *
01074 *                       WORK(IU) is LDA by N and WORK(IR) is LDA by N
01075 *
01076                         LDWRKU = LDA
01077                         IR = IU + LDWRKU*N
01078                         LDWRKR = LDA
01079                      ELSE IF( LWORK.GE.WRKBL+( LDA+N )*N ) THEN
01080 *
01081 *                       WORK(IU) is LDA by N and WORK(IR) is N by N
01082 *
01083                         LDWRKU = LDA
01084                         IR = IU + LDWRKU*N
01085                         LDWRKR = N
01086                      ELSE
01087 *
01088 *                       WORK(IU) is N by N and WORK(IR) is N by N
01089 *
01090                         LDWRKU = N
01091                         IR = IU + LDWRKU*N
01092                         LDWRKR = N
01093                      END IF
01094                      ITAU = IR + LDWRKR*N
01095                      IWORK = ITAU + N
01096 *
01097 *                    Compute A=Q*R
01098 *                    (Workspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)
01099 *
01100                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
01101      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01102 *
01103 *                    Copy R to WORK(IU), zeroing out below it
01104 *
01105                      CALL DLACPY( 'U', N, N, A, LDA, WORK( IU ),
01106      $                            LDWRKU )
01107                      CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
01108      $                            WORK( IU+1 ), LDWRKU )
01109 *
01110 *                    Generate Q in A
01111 *                    (Workspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)
01112 *
01113                      CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
01114      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01115                      IE = ITAU
01116                      ITAUQ = IE + N
01117                      ITAUP = ITAUQ + N
01118                      IWORK = ITAUP + N
01119 *
01120 *                    Bidiagonalize R in WORK(IU), copying result to
01121 *                    WORK(IR)
01122 *                    (Workspace: need 2*N*N+4*N,
01123 *                                prefer 2*N*N+3*N+2*N*NB)
01124 *
01125                      CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,
01126      $                            WORK( IE ), WORK( ITAUQ ),
01127      $                            WORK( ITAUP ), WORK( IWORK ),
01128      $                            LWORK-IWORK+1, IERR )
01129                      CALL DLACPY( 'U', N, N, WORK( IU ), LDWRKU,
01130      $                            WORK( IR ), LDWRKR )
01131 *
01132 *                    Generate left bidiagonalizing vectors in WORK(IU)
01133 *                    (Workspace: need 2*N*N+4*N, prefer 2*N*N+3*N+N*NB)
01134 *
01135                      CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
01136      $                            WORK( ITAUQ ), WORK( IWORK ),
01137      $                            LWORK-IWORK+1, IERR )
01138 *
01139 *                    Generate right bidiagonalizing vectors in WORK(IR)
01140 *                    (Workspace: need 2*N*N+4*N-1,
01141 *                                prefer 2*N*N+3*N+(N-1)*NB)
01142 *
01143                      CALL DORGBR( 'P', N, N, N, WORK( IR ), LDWRKR,
01144      $                            WORK( ITAUP ), WORK( IWORK ),
01145      $                            LWORK-IWORK+1, IERR )
01146                      IWORK = IE + N
01147 *
01148 *                    Perform bidiagonal QR iteration, computing left
01149 *                    singular vectors of R in WORK(IU) and computing
01150 *                    right singular vectors of R in WORK(IR)
01151 *                    (Workspace: need 2*N*N+BDSPAC)
01152 *
01153                      CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ),
01154      $                            WORK( IR ), LDWRKR, WORK( IU ),
01155      $                            LDWRKU, DUM, 1, WORK( IWORK ), INFO )
01156 *
01157 *                    Multiply Q in A by left singular vectors of R in
01158 *                    WORK(IU), storing result in U
01159 *                    (Workspace: need N*N)
01160 *
01161                      CALL DGEMM( 'N', 'N', M, N, N, ONE, A, LDA,
01162      $                           WORK( IU ), LDWRKU, ZERO, U, LDU )
01163 *
01164 *                    Copy right singular vectors of R to A
01165 *                    (Workspace: need N*N)
01166 *
01167                      CALL DLACPY( 'F', N, N, WORK( IR ), LDWRKR, A,
01168      $                            LDA )
01169 *
01170                   ELSE
01171 *
01172 *                    Insufficient workspace for a fast algorithm
01173 *
01174                      ITAU = 1
01175                      IWORK = ITAU + N
01176 *
01177 *                    Compute A=Q*R, copying result to U
01178 *                    (Workspace: need 2*N, prefer N+N*NB)
01179 *
01180                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
01181      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01182                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
01183 *
01184 *                    Generate Q in U
01185 *                    (Workspace: need 2*N, prefer N+N*NB)
01186 *
01187                      CALL DORGQR( M, N, N, U, LDU, WORK( ITAU ),
01188      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01189                      IE = ITAU
01190                      ITAUQ = IE + N
01191                      ITAUP = ITAUQ + N
01192                      IWORK = ITAUP + N
01193 *
01194 *                    Zero out below R in A
01195 *
01196                      CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
01197      $                            LDA )
01198 *
01199 *                    Bidiagonalize R in A
01200 *                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
01201 *
01202                      CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),
01203      $                            WORK( ITAUQ ), WORK( ITAUP ),
01204      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01205 *
01206 *                    Multiply Q in U by left vectors bidiagonalizing R
01207 *                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
01208 *
01209                      CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
01210      $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
01211      $                            LWORK-IWORK+1, IERR )
01212 *
01213 *                    Generate right vectors bidiagonalizing R in A
01214 *                    (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
01215 *
01216                      CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
01217      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01218                      IWORK = IE + N
01219 *
01220 *                    Perform bidiagonal QR iteration, computing left
01221 *                    singular vectors of A in U and computing right
01222 *                    singular vectors of A in A
01223 *                    (Workspace: need BDSPAC)
01224 *
01225                      CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), A,
01226      $                            LDA, U, LDU, DUM, 1, WORK( IWORK ),
01227      $                            INFO )
01228 *
01229                   END IF
01230 *
01231                ELSE IF( WNTVAS ) THEN
01232 *
01233 *                 Path 6 (M much larger than N, JOBU='S', JOBVT='S'
01234 *                         or 'A')
01235 *                 N left singular vectors to be computed in U and
01236 *                 N right singular vectors to be computed in VT
01237 *
01238                   IF( LWORK.GE.N*N+MAX( 4*N, BDSPAC ) ) THEN
01239 *
01240 *                    Sufficient workspace for a fast algorithm
01241 *
01242                      IU = 1
01243                      IF( LWORK.GE.WRKBL+LDA*N ) THEN
01244 *
01245 *                       WORK(IU) is LDA by N
01246 *
01247                         LDWRKU = LDA
01248                      ELSE
01249 *
01250 *                       WORK(IU) is N by N
01251 *
01252                         LDWRKU = N
01253                      END IF
01254                      ITAU = IU + LDWRKU*N
01255                      IWORK = ITAU + N
01256 *
01257 *                    Compute A=Q*R
01258 *                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
01259 *
01260                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
01261      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01262 *
01263 *                    Copy R to WORK(IU), zeroing out below it
01264 *
01265                      CALL DLACPY( 'U', N, N, A, LDA, WORK( IU ),
01266      $                            LDWRKU )
01267                      CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
01268      $                            WORK( IU+1 ), LDWRKU )
01269 *
01270 *                    Generate Q in A
01271 *                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
01272 *
01273                      CALL DORGQR( M, N, N, A, LDA, WORK( ITAU ),
01274      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01275                      IE = ITAU
01276                      ITAUQ = IE + N
01277                      ITAUP = ITAUQ + N
01278                      IWORK = ITAUP + N
01279 *
01280 *                    Bidiagonalize R in WORK(IU), copying result to VT
01281 *                    (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
01282 *
01283                      CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,
01284      $                            WORK( IE ), WORK( ITAUQ ),
01285      $                            WORK( ITAUP ), WORK( IWORK ),
01286      $                            LWORK-IWORK+1, IERR )
01287                      CALL DLACPY( 'U', N, N, WORK( IU ), LDWRKU, VT,
01288      $                            LDVT )
01289 *
01290 *                    Generate left bidiagonalizing vectors in WORK(IU)
01291 *                    (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
01292 *
01293                      CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
01294      $                            WORK( ITAUQ ), WORK( IWORK ),
01295      $                            LWORK-IWORK+1, IERR )
01296 *
01297 *                    Generate right bidiagonalizing vectors in VT
01298 *                    (Workspace: need N*N+4*N-1,
01299 *                                prefer N*N+3*N+(N-1)*NB)
01300 *
01301                      CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
01302      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01303                      IWORK = IE + N
01304 *
01305 *                    Perform bidiagonal QR iteration, computing left
01306 *                    singular vectors of R in WORK(IU) and computing
01307 *                    right singular vectors of R in VT
01308 *                    (Workspace: need N*N+BDSPAC)
01309 *
01310                      CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ), VT,
01311      $                            LDVT, WORK( IU ), LDWRKU, DUM, 1,
01312      $                            WORK( IWORK ), INFO )
01313 *
01314 *                    Multiply Q in A by left singular vectors of R in
01315 *                    WORK(IU), storing result in U
01316 *                    (Workspace: need N*N)
01317 *
01318                      CALL DGEMM( 'N', 'N', M, N, N, ONE, A, LDA,
01319      $                           WORK( IU ), LDWRKU, ZERO, U, LDU )
01320 *
01321                   ELSE
01322 *
01323 *                    Insufficient workspace for a fast algorithm
01324 *
01325                      ITAU = 1
01326                      IWORK = ITAU + N
01327 *
01328 *                    Compute A=Q*R, copying result to U
01329 *                    (Workspace: need 2*N, prefer N+N*NB)
01330 *
01331                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
01332      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01333                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
01334 *
01335 *                    Generate Q in U
01336 *                    (Workspace: need 2*N, prefer N+N*NB)
01337 *
01338                      CALL DORGQR( M, N, N, U, LDU, WORK( ITAU ),
01339      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01340 *
01341 *                    Copy R to VT, zeroing out below it
01342 *
01343                      CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )
01344                      IF( N.GT.1 )
01345      $                  CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
01346      $                               VT( 2, 1 ), LDVT )
01347                      IE = ITAU
01348                      ITAUQ = IE + N
01349                      ITAUP = ITAUQ + N
01350                      IWORK = ITAUP + N
01351 *
01352 *                    Bidiagonalize R in VT
01353 *                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
01354 *
01355                      CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),
01356      $                            WORK( ITAUQ ), WORK( ITAUP ),
01357      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01358 *
01359 *                    Multiply Q in U by left bidiagonalizing vectors
01360 *                    in VT
01361 *                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
01362 *
01363                      CALL DORMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
01364      $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
01365      $                            LWORK-IWORK+1, IERR )
01366 *
01367 *                    Generate right bidiagonalizing vectors in VT
01368 *                    (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
01369 *
01370                      CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
01371      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01372                      IWORK = IE + N
01373 *
01374 *                    Perform bidiagonal QR iteration, computing left
01375 *                    singular vectors of A in U and computing right
01376 *                    singular vectors of A in VT
01377 *                    (Workspace: need BDSPAC)
01378 *
01379                      CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), VT,
01380      $                            LDVT, U, LDU, DUM, 1, WORK( IWORK ),
01381      $                            INFO )
01382 *
01383                   END IF
01384 *
01385                END IF
01386 *
01387             ELSE IF( WNTUA ) THEN
01388 *
01389                IF( WNTVN ) THEN
01390 *
01391 *                 Path 7 (M much larger than N, JOBU='A', JOBVT='N')
01392 *                 M left singular vectors to be computed in U and
01393 *                 no right singular vectors to be computed
01394 *
01395                   IF( LWORK.GE.N*N+MAX( N+M, 4*N, BDSPAC ) ) THEN
01396 *
01397 *                    Sufficient workspace for a fast algorithm
01398 *
01399                      IR = 1
01400                      IF( LWORK.GE.WRKBL+LDA*N ) THEN
01401 *
01402 *                       WORK(IR) is LDA by N
01403 *
01404                         LDWRKR = LDA
01405                      ELSE
01406 *
01407 *                       WORK(IR) is N by N
01408 *
01409                         LDWRKR = N
01410                      END IF
01411                      ITAU = IR + LDWRKR*N
01412                      IWORK = ITAU + N
01413 *
01414 *                    Compute A=Q*R, copying result to U
01415 *                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
01416 *
01417                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
01418      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01419                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
01420 *
01421 *                    Copy R to WORK(IR), zeroing out below it
01422 *
01423                      CALL DLACPY( 'U', N, N, A, LDA, WORK( IR ),
01424      $                            LDWRKR )
01425                      CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
01426      $                            WORK( IR+1 ), LDWRKR )
01427 *
01428 *                    Generate Q in U
01429 *                    (Workspace: need N*N+N+M, prefer N*N+N+M*NB)
01430 *
01431                      CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
01432      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01433                      IE = ITAU
01434                      ITAUQ = IE + N
01435                      ITAUP = ITAUQ + N
01436                      IWORK = ITAUP + N
01437 *
01438 *                    Bidiagonalize R in WORK(IR)
01439 *                    (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
01440 *
01441                      CALL DGEBRD( N, N, WORK( IR ), LDWRKR, S,
01442      $                            WORK( IE ), WORK( ITAUQ ),
01443      $                            WORK( ITAUP ), WORK( IWORK ),
01444      $                            LWORK-IWORK+1, IERR )
01445 *
01446 *                    Generate left bidiagonalizing vectors in WORK(IR)
01447 *                    (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
01448 *
01449                      CALL DORGBR( 'Q', N, N, N, WORK( IR ), LDWRKR,
01450      $                            WORK( ITAUQ ), WORK( IWORK ),
01451      $                            LWORK-IWORK+1, IERR )
01452                      IWORK = IE + N
01453 *
01454 *                    Perform bidiagonal QR iteration, computing left
01455 *                    singular vectors of R in WORK(IR)
01456 *                    (Workspace: need N*N+BDSPAC)
01457 *
01458                      CALL DBDSQR( 'U', N, 0, N, 0, S, WORK( IE ), DUM,
01459      $                            1, WORK( IR ), LDWRKR, DUM, 1,
01460      $                            WORK( IWORK ), INFO )
01461 *
01462 *                    Multiply Q in U by left singular vectors of R in
01463 *                    WORK(IR), storing result in A
01464 *                    (Workspace: need N*N)
01465 *
01466                      CALL DGEMM( 'N', 'N', M, N, N, ONE, U, LDU,
01467      $                           WORK( IR ), LDWRKR, ZERO, A, LDA )
01468 *
01469 *                    Copy left singular vectors of A from A to U
01470 *
01471                      CALL DLACPY( 'F', M, N, A, LDA, U, LDU )
01472 *
01473                   ELSE
01474 *
01475 *                    Insufficient workspace for a fast algorithm
01476 *
01477                      ITAU = 1
01478                      IWORK = ITAU + N
01479 *
01480 *                    Compute A=Q*R, copying result to U
01481 *                    (Workspace: need 2*N, prefer N+N*NB)
01482 *
01483                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
01484      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01485                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
01486 *
01487 *                    Generate Q in U
01488 *                    (Workspace: need N+M, prefer N+M*NB)
01489 *
01490                      CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
01491      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01492                      IE = ITAU
01493                      ITAUQ = IE + N
01494                      ITAUP = ITAUQ + N
01495                      IWORK = ITAUP + N
01496 *
01497 *                    Zero out below R in A
01498 *
01499                      CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
01500      $                            LDA )
01501 *
01502 *                    Bidiagonalize R in A
01503 *                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
01504 *
01505                      CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),
01506      $                            WORK( ITAUQ ), WORK( ITAUP ),
01507      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01508 *
01509 *                    Multiply Q in U by left bidiagonalizing vectors
01510 *                    in A
01511 *                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
01512 *
01513                      CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
01514      $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
01515      $                            LWORK-IWORK+1, IERR )
01516                      IWORK = IE + N
01517 *
01518 *                    Perform bidiagonal QR iteration, computing left
01519 *                    singular vectors of A in U
01520 *                    (Workspace: need BDSPAC)
01521 *
01522                      CALL DBDSQR( 'U', N, 0, M, 0, S, WORK( IE ), DUM,
01523      $                            1, U, LDU, DUM, 1, WORK( IWORK ),
01524      $                            INFO )
01525 *
01526                   END IF
01527 *
01528                ELSE IF( WNTVO ) THEN
01529 *
01530 *                 Path 8 (M much larger than N, JOBU='A', JOBVT='O')
01531 *                 M left singular vectors to be computed in U and
01532 *                 N right singular vectors to be overwritten on A
01533 *
01534                   IF( LWORK.GE.2*N*N+MAX( N+M, 4*N, BDSPAC ) ) THEN
01535 *
01536 *                    Sufficient workspace for a fast algorithm
01537 *
01538                      IU = 1
01539                      IF( LWORK.GE.WRKBL+2*LDA*N ) THEN
01540 *
01541 *                       WORK(IU) is LDA by N and WORK(IR) is LDA by N
01542 *
01543                         LDWRKU = LDA
01544                         IR = IU + LDWRKU*N
01545                         LDWRKR = LDA
01546                      ELSE IF( LWORK.GE.WRKBL+( LDA+N )*N ) THEN
01547 *
01548 *                       WORK(IU) is LDA by N and WORK(IR) is N by N
01549 *
01550                         LDWRKU = LDA
01551                         IR = IU + LDWRKU*N
01552                         LDWRKR = N
01553                      ELSE
01554 *
01555 *                       WORK(IU) is N by N and WORK(IR) is N by N
01556 *
01557                         LDWRKU = N
01558                         IR = IU + LDWRKU*N
01559                         LDWRKR = N
01560                      END IF
01561                      ITAU = IR + LDWRKR*N
01562                      IWORK = ITAU + N
01563 *
01564 *                    Compute A=Q*R, copying result to U
01565 *                    (Workspace: need 2*N*N+2*N, prefer 2*N*N+N+N*NB)
01566 *
01567                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
01568      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01569                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
01570 *
01571 *                    Generate Q in U
01572 *                    (Workspace: need 2*N*N+N+M, prefer 2*N*N+N+M*NB)
01573 *
01574                      CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
01575      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01576 *
01577 *                    Copy R to WORK(IU), zeroing out below it
01578 *
01579                      CALL DLACPY( 'U', N, N, A, LDA, WORK( IU ),
01580      $                            LDWRKU )
01581                      CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
01582      $                            WORK( IU+1 ), LDWRKU )
01583                      IE = ITAU
01584                      ITAUQ = IE + N
01585                      ITAUP = ITAUQ + N
01586                      IWORK = ITAUP + N
01587 *
01588 *                    Bidiagonalize R in WORK(IU), copying result to
01589 *                    WORK(IR)
01590 *                    (Workspace: need 2*N*N+4*N,
01591 *                                prefer 2*N*N+3*N+2*N*NB)
01592 *
01593                      CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,
01594      $                            WORK( IE ), WORK( ITAUQ ),
01595      $                            WORK( ITAUP ), WORK( IWORK ),
01596      $                            LWORK-IWORK+1, IERR )
01597                      CALL DLACPY( 'U', N, N, WORK( IU ), LDWRKU,
01598      $                            WORK( IR ), LDWRKR )
01599 *
01600 *                    Generate left bidiagonalizing vectors in WORK(IU)
01601 *                    (Workspace: need 2*N*N+4*N, prefer 2*N*N+3*N+N*NB)
01602 *
01603                      CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
01604      $                            WORK( ITAUQ ), WORK( IWORK ),
01605      $                            LWORK-IWORK+1, IERR )
01606 *
01607 *                    Generate right bidiagonalizing vectors in WORK(IR)
01608 *                    (Workspace: need 2*N*N+4*N-1,
01609 *                                prefer 2*N*N+3*N+(N-1)*NB)
01610 *
01611                      CALL DORGBR( 'P', N, N, N, WORK( IR ), LDWRKR,
01612      $                            WORK( ITAUP ), WORK( IWORK ),
01613      $                            LWORK-IWORK+1, IERR )
01614                      IWORK = IE + N
01615 *
01616 *                    Perform bidiagonal QR iteration, computing left
01617 *                    singular vectors of R in WORK(IU) and computing
01618 *                    right singular vectors of R in WORK(IR)
01619 *                    (Workspace: need 2*N*N+BDSPAC)
01620 *
01621                      CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ),
01622      $                            WORK( IR ), LDWRKR, WORK( IU ),
01623      $                            LDWRKU, DUM, 1, WORK( IWORK ), INFO )
01624 *
01625 *                    Multiply Q in U by left singular vectors of R in
01626 *                    WORK(IU), storing result in A
01627 *                    (Workspace: need N*N)
01628 *
01629                      CALL DGEMM( 'N', 'N', M, N, N, ONE, U, LDU,
01630      $                           WORK( IU ), LDWRKU, ZERO, A, LDA )
01631 *
01632 *                    Copy left singular vectors of A from A to U
01633 *
01634                      CALL DLACPY( 'F', M, N, A, LDA, U, LDU )
01635 *
01636 *                    Copy right singular vectors of R from WORK(IR) to A
01637 *
01638                      CALL DLACPY( 'F', N, N, WORK( IR ), LDWRKR, A,
01639      $                            LDA )
01640 *
01641                   ELSE
01642 *
01643 *                    Insufficient workspace for a fast algorithm
01644 *
01645                      ITAU = 1
01646                      IWORK = ITAU + N
01647 *
01648 *                    Compute A=Q*R, copying result to U
01649 *                    (Workspace: need 2*N, prefer N+N*NB)
01650 *
01651                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
01652      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01653                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
01654 *
01655 *                    Generate Q in U
01656 *                    (Workspace: need N+M, prefer N+M*NB)
01657 *
01658                      CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
01659      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01660                      IE = ITAU
01661                      ITAUQ = IE + N
01662                      ITAUP = ITAUQ + N
01663                      IWORK = ITAUP + N
01664 *
01665 *                    Zero out below R in A
01666 *
01667                      CALL DLASET( 'L', N-1, N-1, ZERO, ZERO, A( 2, 1 ),
01668      $                            LDA )
01669 *
01670 *                    Bidiagonalize R in A
01671 *                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
01672 *
01673                      CALL DGEBRD( N, N, A, LDA, S, WORK( IE ),
01674      $                            WORK( ITAUQ ), WORK( ITAUP ),
01675      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01676 *
01677 *                    Multiply Q in U by left bidiagonalizing vectors
01678 *                    in A
01679 *                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
01680 *
01681                      CALL DORMBR( 'Q', 'R', 'N', M, N, N, A, LDA,
01682      $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
01683      $                            LWORK-IWORK+1, IERR )
01684 *
01685 *                    Generate right bidiagonalizing vectors in A
01686 *                    (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
01687 *
01688                      CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
01689      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01690                      IWORK = IE + N
01691 *
01692 *                    Perform bidiagonal QR iteration, computing left
01693 *                    singular vectors of A in U and computing right
01694 *                    singular vectors of A in A
01695 *                    (Workspace: need BDSPAC)
01696 *
01697                      CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), A,
01698      $                            LDA, U, LDU, DUM, 1, WORK( IWORK ),
01699      $                            INFO )
01700 *
01701                   END IF
01702 *
01703                ELSE IF( WNTVAS ) THEN
01704 *
01705 *                 Path 9 (M much larger than N, JOBU='A', JOBVT='S'
01706 *                         or 'A')
01707 *                 M left singular vectors to be computed in U and
01708 *                 N right singular vectors to be computed in VT
01709 *
01710                   IF( LWORK.GE.N*N+MAX( N+M, 4*N, BDSPAC ) ) THEN
01711 *
01712 *                    Sufficient workspace for a fast algorithm
01713 *
01714                      IU = 1
01715                      IF( LWORK.GE.WRKBL+LDA*N ) THEN
01716 *
01717 *                       WORK(IU) is LDA by N
01718 *
01719                         LDWRKU = LDA
01720                      ELSE
01721 *
01722 *                       WORK(IU) is N by N
01723 *
01724                         LDWRKU = N
01725                      END IF
01726                      ITAU = IU + LDWRKU*N
01727                      IWORK = ITAU + N
01728 *
01729 *                    Compute A=Q*R, copying result to U
01730 *                    (Workspace: need N*N+2*N, prefer N*N+N+N*NB)
01731 *
01732                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
01733      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01734                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
01735 *
01736 *                    Generate Q in U
01737 *                    (Workspace: need N*N+N+M, prefer N*N+N+M*NB)
01738 *
01739                      CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
01740      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01741 *
01742 *                    Copy R to WORK(IU), zeroing out below it
01743 *
01744                      CALL DLACPY( 'U', N, N, A, LDA, WORK( IU ),
01745      $                            LDWRKU )
01746                      CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
01747      $                            WORK( IU+1 ), LDWRKU )
01748                      IE = ITAU
01749                      ITAUQ = IE + N
01750                      ITAUP = ITAUQ + N
01751                      IWORK = ITAUP + N
01752 *
01753 *                    Bidiagonalize R in WORK(IU), copying result to VT
01754 *                    (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB)
01755 *
01756                      CALL DGEBRD( N, N, WORK( IU ), LDWRKU, S,
01757      $                            WORK( IE ), WORK( ITAUQ ),
01758      $                            WORK( ITAUP ), WORK( IWORK ),
01759      $                            LWORK-IWORK+1, IERR )
01760                      CALL DLACPY( 'U', N, N, WORK( IU ), LDWRKU, VT,
01761      $                            LDVT )
01762 *
01763 *                    Generate left bidiagonalizing vectors in WORK(IU)
01764 *                    (Workspace: need N*N+4*N, prefer N*N+3*N+N*NB)
01765 *
01766                      CALL DORGBR( 'Q', N, N, N, WORK( IU ), LDWRKU,
01767      $                            WORK( ITAUQ ), WORK( IWORK ),
01768      $                            LWORK-IWORK+1, IERR )
01769 *
01770 *                    Generate right bidiagonalizing vectors in VT
01771 *                    (Workspace: need N*N+4*N-1,
01772 *                                prefer N*N+3*N+(N-1)*NB)
01773 *
01774                      CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
01775      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01776                      IWORK = IE + N
01777 *
01778 *                    Perform bidiagonal QR iteration, computing left
01779 *                    singular vectors of R in WORK(IU) and computing
01780 *                    right singular vectors of R in VT
01781 *                    (Workspace: need N*N+BDSPAC)
01782 *
01783                      CALL DBDSQR( 'U', N, N, N, 0, S, WORK( IE ), VT,
01784      $                            LDVT, WORK( IU ), LDWRKU, DUM, 1,
01785      $                            WORK( IWORK ), INFO )
01786 *
01787 *                    Multiply Q in U by left singular vectors of R in
01788 *                    WORK(IU), storing result in A
01789 *                    (Workspace: need N*N)
01790 *
01791                      CALL DGEMM( 'N', 'N', M, N, N, ONE, U, LDU,
01792      $                           WORK( IU ), LDWRKU, ZERO, A, LDA )
01793 *
01794 *                    Copy left singular vectors of A from A to U
01795 *
01796                      CALL DLACPY( 'F', M, N, A, LDA, U, LDU )
01797 *
01798                   ELSE
01799 *
01800 *                    Insufficient workspace for a fast algorithm
01801 *
01802                      ITAU = 1
01803                      IWORK = ITAU + N
01804 *
01805 *                    Compute A=Q*R, copying result to U
01806 *                    (Workspace: need 2*N, prefer N+N*NB)
01807 *
01808                      CALL DGEQRF( M, N, A, LDA, WORK( ITAU ),
01809      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01810                      CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
01811 *
01812 *                    Generate Q in U
01813 *                    (Workspace: need N+M, prefer N+M*NB)
01814 *
01815                      CALL DORGQR( M, M, N, U, LDU, WORK( ITAU ),
01816      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01817 *
01818 *                    Copy R from A to VT, zeroing out below it
01819 *
01820                      CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )
01821                      IF( N.GT.1 )
01822      $                  CALL DLASET( 'L', N-1, N-1, ZERO, ZERO,
01823      $                               VT( 2, 1 ), LDVT )
01824                      IE = ITAU
01825                      ITAUQ = IE + N
01826                      ITAUP = ITAUQ + N
01827                      IWORK = ITAUP + N
01828 *
01829 *                    Bidiagonalize R in VT
01830 *                    (Workspace: need 4*N, prefer 3*N+2*N*NB)
01831 *
01832                      CALL DGEBRD( N, N, VT, LDVT, S, WORK( IE ),
01833      $                            WORK( ITAUQ ), WORK( ITAUP ),
01834      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01835 *
01836 *                    Multiply Q in U by left bidiagonalizing vectors
01837 *                    in VT
01838 *                    (Workspace: need 3*N+M, prefer 3*N+M*NB)
01839 *
01840                      CALL DORMBR( 'Q', 'R', 'N', M, N, N, VT, LDVT,
01841      $                            WORK( ITAUQ ), U, LDU, WORK( IWORK ),
01842      $                            LWORK-IWORK+1, IERR )
01843 *
01844 *                    Generate right bidiagonalizing vectors in VT
01845 *                    (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
01846 *
01847                      CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
01848      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
01849                      IWORK = IE + N
01850 *
01851 *                    Perform bidiagonal QR iteration, computing left
01852 *                    singular vectors of A in U and computing right
01853 *                    singular vectors of A in VT
01854 *                    (Workspace: need BDSPAC)
01855 *
01856                      CALL DBDSQR( 'U', N, N, M, 0, S, WORK( IE ), VT,
01857      $                            LDVT, U, LDU, DUM, 1, WORK( IWORK ),
01858      $                            INFO )
01859 *
01860                   END IF
01861 *
01862                END IF
01863 *
01864             END IF
01865 *
01866          ELSE
01867 *
01868 *           M .LT. MNTHR
01869 *
01870 *           Path 10 (M at least N, but not much larger)
01871 *           Reduce to bidiagonal form without QR decomposition
01872 *
01873             IE = 1
01874             ITAUQ = IE + N
01875             ITAUP = ITAUQ + N
01876             IWORK = ITAUP + N
01877 *
01878 *           Bidiagonalize A
01879 *           (Workspace: need 3*N+M, prefer 3*N+(M+N)*NB)
01880 *
01881             CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
01882      $                   WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
01883      $                   IERR )
01884             IF( WNTUAS ) THEN
01885 *
01886 *              If left singular vectors desired in U, copy result to U
01887 *              and generate left bidiagonalizing vectors in U
01888 *              (Workspace: need 3*N+NCU, prefer 3*N+NCU*NB)
01889 *
01890                CALL DLACPY( 'L', M, N, A, LDA, U, LDU )
01891                IF( WNTUS )
01892      $            NCU = N
01893                IF( WNTUA )
01894      $            NCU = M
01895                CALL DORGBR( 'Q', M, NCU, N, U, LDU, WORK( ITAUQ ),
01896      $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
01897             END IF
01898             IF( WNTVAS ) THEN
01899 *
01900 *              If right singular vectors desired in VT, copy result to
01901 *              VT and generate right bidiagonalizing vectors in VT
01902 *              (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
01903 *
01904                CALL DLACPY( 'U', N, N, A, LDA, VT, LDVT )
01905                CALL DORGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
01906      $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
01907             END IF
01908             IF( WNTUO ) THEN
01909 *
01910 *              If left singular vectors desired in A, generate left
01911 *              bidiagonalizing vectors in A
01912 *              (Workspace: need 4*N, prefer 3*N+N*NB)
01913 *
01914                CALL DORGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
01915      $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
01916             END IF
01917             IF( WNTVO ) THEN
01918 *
01919 *              If right singular vectors desired in A, generate right
01920 *              bidiagonalizing vectors in A
01921 *              (Workspace: need 4*N-1, prefer 3*N+(N-1)*NB)
01922 *
01923                CALL DORGBR( 'P', N, N, N, A, LDA, WORK( ITAUP ),
01924      $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
01925             END IF
01926             IWORK = IE + N
01927             IF( WNTUAS .OR. WNTUO )
01928      $         NRU = M
01929             IF( WNTUN )
01930      $         NRU = 0
01931             IF( WNTVAS .OR. WNTVO )
01932      $         NCVT = N
01933             IF( WNTVN )
01934      $         NCVT = 0
01935             IF( ( .NOT.WNTUO ) .AND. ( .NOT.WNTVO ) ) THEN
01936 *
01937 *              Perform bidiagonal QR iteration, if desired, computing
01938 *              left singular vectors in U and computing right singular
01939 *              vectors in VT
01940 *              (Workspace: need BDSPAC)
01941 *
01942                CALL DBDSQR( 'U', N, NCVT, NRU, 0, S, WORK( IE ), VT,
01943      $                      LDVT, U, LDU, DUM, 1, WORK( IWORK ), INFO )
01944             ELSE IF( ( .NOT.WNTUO ) .AND. WNTVO ) THEN
01945 *
01946 *              Perform bidiagonal QR iteration, if desired, computing
01947 *              left singular vectors in U and computing right singular
01948 *              vectors in A
01949 *              (Workspace: need BDSPAC)
01950 *
01951                CALL DBDSQR( 'U', N, NCVT, NRU, 0, S, WORK( IE ), A, LDA,
01952      $                      U, LDU, DUM, 1, WORK( IWORK ), INFO )
01953             ELSE
01954 *
01955 *              Perform bidiagonal QR iteration, if desired, computing
01956 *              left singular vectors in A and computing right singular
01957 *              vectors in VT
01958 *              (Workspace: need BDSPAC)
01959 *
01960                CALL DBDSQR( 'U', N, NCVT, NRU, 0, S, WORK( IE ), VT,
01961      $                      LDVT, A, LDA, DUM, 1, WORK( IWORK ), INFO )
01962             END IF
01963 *
01964          END IF
01965 *
01966       ELSE
01967 *
01968 *        A has more columns than rows. If A has sufficiently more
01969 *        columns than rows, first reduce using the LQ decomposition (if
01970 *        sufficient workspace available)
01971 *
01972          IF( N.GE.MNTHR ) THEN
01973 *
01974             IF( WNTVN ) THEN
01975 *
01976 *              Path 1t(N much larger than M, JOBVT='N')
01977 *              No right singular vectors to be computed
01978 *
01979                ITAU = 1
01980                IWORK = ITAU + M
01981 *
01982 *              Compute A=L*Q
01983 *              (Workspace: need 2*M, prefer M+M*NB)
01984 *
01985                CALL DGELQF( M, N, A, LDA, WORK( ITAU ), WORK( IWORK ),
01986      $                      LWORK-IWORK+1, IERR )
01987 *
01988 *              Zero out above L
01989 *
01990                CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ), LDA )
01991                IE = 1
01992                ITAUQ = IE + M
01993                ITAUP = ITAUQ + M
01994                IWORK = ITAUP + M
01995 *
01996 *              Bidiagonalize L in A
01997 *              (Workspace: need 4*M, prefer 3*M+2*M*NB)
01998 *
01999                CALL DGEBRD( M, M, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
02000      $                      WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
02001      $                      IERR )
02002                IF( WNTUO .OR. WNTUAS ) THEN
02003 *
02004 *                 If left singular vectors desired, generate Q
02005 *                 (Workspace: need 4*M, prefer 3*M+M*NB)
02006 *
02007                   CALL DORGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
02008      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
02009                END IF
02010                IWORK = IE + M
02011                NRU = 0
02012                IF( WNTUO .OR. WNTUAS )
02013      $            NRU = M
02014 *
02015 *              Perform bidiagonal QR iteration, computing left singular
02016 *              vectors of A in A if desired
02017 *              (Workspace: need BDSPAC)
02018 *
02019                CALL DBDSQR( 'U', M, 0, NRU, 0, S, WORK( IE ), DUM, 1, A,
02020      $                      LDA, DUM, 1, WORK( IWORK ), INFO )
02021 *
02022 *              If left singular vectors desired in U, copy them there
02023 *
02024                IF( WNTUAS )
02025      $            CALL DLACPY( 'F', M, M, A, LDA, U, LDU )
02026 *
02027             ELSE IF( WNTVO .AND. WNTUN ) THEN
02028 *
02029 *              Path 2t(N much larger than M, JOBU='N', JOBVT='O')
02030 *              M right singular vectors to be overwritten on A and
02031 *              no left singular vectors to be computed
02032 *
02033                IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN
02034 *
02035 *                 Sufficient workspace for a fast algorithm
02036 *
02037                   IR = 1
02038                   IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+LDA*M ) THEN
02039 *
02040 *                    WORK(IU) is LDA by N and WORK(IR) is LDA by M
02041 *
02042                      LDWRKU = LDA
02043                      CHUNK = N
02044                      LDWRKR = LDA
02045                   ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+M*M ) THEN
02046 *
02047 *                    WORK(IU) is LDA by N and WORK(IR) is M by M
02048 *
02049                      LDWRKU = LDA
02050                      CHUNK = N
02051                      LDWRKR = M
02052                   ELSE
02053 *
02054 *                    WORK(IU) is M by CHUNK and WORK(IR) is M by M
02055 *
02056                      LDWRKU = M
02057                      CHUNK = ( LWORK-M*M-M ) / M
02058                      LDWRKR = M
02059                   END IF
02060                   ITAU = IR + LDWRKR*M
02061                   IWORK = ITAU + M
02062 *
02063 *                 Compute A=L*Q
02064 *                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
02065 *
02066                   CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
02067      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
02068 *
02069 *                 Copy L to WORK(IR) and zero out above it
02070 *
02071                   CALL DLACPY( 'L', M, M, A, LDA, WORK( IR ), LDWRKR )
02072                   CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
02073      $                         WORK( IR+LDWRKR ), LDWRKR )
02074 *
02075 *                 Generate Q in A
02076 *                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
02077 *
02078                   CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
02079      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
02080                   IE = ITAU
02081                   ITAUQ = IE + M
02082                   ITAUP = ITAUQ + M
02083                   IWORK = ITAUP + M
02084 *
02085 *                 Bidiagonalize L in WORK(IR)
02086 *                 (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
02087 *
02088                   CALL DGEBRD( M, M, WORK( IR ), LDWRKR, S, WORK( IE ),
02089      $                         WORK( ITAUQ ), WORK( ITAUP ),
02090      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
02091 *
02092 *                 Generate right vectors bidiagonalizing L
02093 *                 (Workspace: need M*M+4*M-1, prefer M*M+3*M+(M-1)*NB)
02094 *
02095                   CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
02096      $                         WORK( ITAUP ), WORK( IWORK ),
02097      $                         LWORK-IWORK+1, IERR )
02098                   IWORK = IE + M
02099 *
02100 *                 Perform bidiagonal QR iteration, computing right
02101 *                 singular vectors of L in WORK(IR)
02102 *                 (Workspace: need M*M+BDSPAC)
02103 *
02104                   CALL DBDSQR( 'U', M, M, 0, 0, S, WORK( IE ),
02105      $                         WORK( IR ), LDWRKR, DUM, 1, DUM, 1,
02106      $                         WORK( IWORK ), INFO )
02107                   IU = IE + M
02108 *
02109 *                 Multiply right singular vectors of L in WORK(IR) by Q
02110 *                 in A, storing result in WORK(IU) and copying to A
02111 *                 (Workspace: need M*M+2*M, prefer M*M+M*N+M)
02112 *
02113                   DO 30 I = 1, N, CHUNK
02114                      BLK = MIN( N-I+1, CHUNK )
02115                      CALL DGEMM( 'N', 'N', M, BLK, M, ONE, WORK( IR ),
02116      $                           LDWRKR, A( 1, I ), LDA, ZERO,
02117      $                           WORK( IU ), LDWRKU )
02118                      CALL DLACPY( 'F', M, BLK, WORK( IU ), LDWRKU,
02119      $                            A( 1, I ), LDA )
02120    30             CONTINUE
02121 *
02122                ELSE
02123 *
02124 *                 Insufficient workspace for a fast algorithm
02125 *
02126                   IE = 1
02127                   ITAUQ = IE + M
02128                   ITAUP = ITAUQ + M
02129                   IWORK = ITAUP + M
02130 *
02131 *                 Bidiagonalize A
02132 *                 (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)
02133 *
02134                   CALL DGEBRD( M, N, A, LDA, S, WORK( IE ),
02135      $                         WORK( ITAUQ ), WORK( ITAUP ),
02136      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
02137 *
02138 *                 Generate right vectors bidiagonalizing A
02139 *                 (Workspace: need 4*M, prefer 3*M+M*NB)
02140 *
02141                   CALL DORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
02142      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
02143                   IWORK = IE + M
02144 *
02145 *                 Perform bidiagonal QR iteration, computing right
02146 *                 singular vectors of A in A
02147 *                 (Workspace: need BDSPAC)
02148 *
02149                   CALL DBDSQR( 'L', M, N, 0, 0, S, WORK( IE ), A, LDA,
02150      $                         DUM, 1, DUM, 1, WORK( IWORK ), INFO )
02151 *
02152                END IF
02153 *
02154             ELSE IF( WNTVO .AND. WNTUAS ) THEN
02155 *
02156 *              Path 3t(N much larger than M, JOBU='S' or 'A', JOBVT='O')
02157 *              M right singular vectors to be overwritten on A and
02158 *              M left singular vectors to be computed in U
02159 *
02160                IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN
02161 *
02162 *                 Sufficient workspace for a fast algorithm
02163 *
02164                   IR = 1
02165                   IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+LDA*M ) THEN
02166 *
02167 *                    WORK(IU) is LDA by N and WORK(IR) is LDA by M
02168 *
02169                      LDWRKU = LDA
02170                      CHUNK = N
02171                      LDWRKR = LDA
02172                   ELSE IF( LWORK.GE.MAX( WRKBL, LDA*N+M )+M*M ) THEN
02173 *
02174 *                    WORK(IU) is LDA by N and WORK(IR) is M by M
02175 *
02176                      LDWRKU = LDA
02177                      CHUNK = N
02178                      LDWRKR = M
02179                   ELSE
02180 *
02181 *                    WORK(IU) is M by CHUNK and WORK(IR) is M by M
02182 *
02183                      LDWRKU = M
02184                      CHUNK = ( LWORK-M*M-M ) / M
02185                      LDWRKR = M
02186                   END IF
02187                   ITAU = IR + LDWRKR*M
02188                   IWORK = ITAU + M
02189 *
02190 *                 Compute A=L*Q
02191 *                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
02192 *
02193                   CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
02194      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
02195 *
02196 *                 Copy L to U, zeroing about above it
02197 *
02198                   CALL DLACPY( 'L', M, M, A, LDA, U, LDU )
02199                   CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),
02200      $                         LDU )
02201 *
02202 *                 Generate Q in A
02203 *                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
02204 *
02205                   CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
02206      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
02207                   IE = ITAU
02208                   ITAUQ = IE + M
02209                   ITAUP = ITAUQ + M
02210                   IWORK = ITAUP + M
02211 *
02212 *                 Bidiagonalize L in U, copying result to WORK(IR)
02213 *                 (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
02214 *
02215                   CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),
02216      $                         WORK( ITAUQ ), WORK( ITAUP ),
02217      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
02218                   CALL DLACPY( 'U', M, M, U, LDU, WORK( IR ), LDWRKR )
02219 *
02220 *                 Generate right vectors bidiagonalizing L in WORK(IR)
02221 *                 (Workspace: need M*M+4*M-1, prefer M*M+3*M+(M-1)*NB)
02222 *
02223                   CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
02224      $                         WORK( ITAUP ), WORK( IWORK ),
02225      $                         LWORK-IWORK+1, IERR )
02226 *
02227 *                 Generate left vectors bidiagonalizing L in U
02228 *                 (Workspace: need M*M+4*M, prefer M*M+3*M+M*NB)
02229 *
02230                   CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
02231      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
02232                   IWORK = IE + M
02233 *
02234 *                 Perform bidiagonal QR iteration, computing left
02235 *                 singular vectors of L in U, and computing right
02236 *                 singular vectors of L in WORK(IR)
02237 *                 (Workspace: need M*M+BDSPAC)
02238 *
02239                   CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
02240      $                         WORK( IR ), LDWRKR, U, LDU, DUM, 1,
02241      $                         WORK( IWORK ), INFO )
02242                   IU = IE + M
02243 *
02244 *                 Multiply right singular vectors of L in WORK(IR) by Q
02245 *                 in A, storing result in WORK(IU) and copying to A
02246 *                 (Workspace: need M*M+2*M, prefer M*M+M*N+M))
02247 *
02248                   DO 40 I = 1, N, CHUNK
02249                      BLK = MIN( N-I+1, CHUNK )
02250                      CALL DGEMM( 'N', 'N', M, BLK, M, ONE, WORK( IR ),
02251      $                           LDWRKR, A( 1, I ), LDA, ZERO,
02252      $                           WORK( IU ), LDWRKU )
02253                      CALL DLACPY( 'F', M, BLK, WORK( IU ), LDWRKU,
02254      $                            A( 1, I ), LDA )
02255    40             CONTINUE
02256 *
02257                ELSE
02258 *
02259 *                 Insufficient workspace for a fast algorithm
02260 *
02261                   ITAU = 1
02262                   IWORK = ITAU + M
02263 *
02264 *                 Compute A=L*Q
02265 *                 (Workspace: need 2*M, prefer M+M*NB)
02266 *
02267                   CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
02268      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
02269 *
02270 *                 Copy L to U, zeroing out above it
02271 *
02272                   CALL DLACPY( 'L', M, M, A, LDA, U, LDU )
02273                   CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),
02274      $                         LDU )
02275 *
02276 *                 Generate Q in A
02277 *                 (Workspace: need 2*M, prefer M+M*NB)
02278 *
02279                   CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
02280      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
02281                   IE = ITAU
02282                   ITAUQ = IE + M
02283                   ITAUP = ITAUQ + M
02284                   IWORK = ITAUP + M
02285 *
02286 *                 Bidiagonalize L in U
02287 *                 (Workspace: need 4*M, prefer 3*M+2*M*NB)
02288 *
02289                   CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),
02290      $                         WORK( ITAUQ ), WORK( ITAUP ),
02291      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
02292 *
02293 *                 Multiply right vectors bidiagonalizing L by Q in A
02294 *                 (Workspace: need 3*M+N, prefer 3*M+N*NB)
02295 *
02296                   CALL DORMBR( 'P', 'L', 'T', M, N, M, U, LDU,
02297      $                         WORK( ITAUP ), A, LDA, WORK( IWORK ),
02298      $                         LWORK-IWORK+1, IERR )
02299 *
02300 *                 Generate left vectors bidiagonalizing L in U
02301 *                 (Workspace: need 4*M, prefer 3*M+M*NB)
02302 *
02303                   CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
02304      $                         WORK( IWORK ), LWORK-IWORK+1, IERR )
02305                   IWORK = IE + M
02306 *
02307 *                 Perform bidiagonal QR iteration, computing left
02308 *                 singular vectors of A in U and computing right
02309 *                 singular vectors of A in A
02310 *                 (Workspace: need BDSPAC)
02311 *
02312                   CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), A, LDA,
02313      $                         U, LDU, DUM, 1, WORK( IWORK ), INFO )
02314 *
02315                END IF
02316 *
02317             ELSE IF( WNTVS ) THEN
02318 *
02319                IF( WNTUN ) THEN
02320 *
02321 *                 Path 4t(N much larger than M, JOBU='N', JOBVT='S')
02322 *                 M right singular vectors to be computed in VT and
02323 *                 no left singular vectors to be computed
02324 *
02325                   IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN
02326 *
02327 *                    Sufficient workspace for a fast algorithm
02328 *
02329                      IR = 1
02330                      IF( LWORK.GE.WRKBL+LDA*M ) THEN
02331 *
02332 *                       WORK(IR) is LDA by M
02333 *
02334                         LDWRKR = LDA
02335                      ELSE
02336 *
02337 *                       WORK(IR) is M by M
02338 *
02339                         LDWRKR = M
02340                      END IF
02341                      ITAU = IR + LDWRKR*M
02342                      IWORK = ITAU + M
02343 *
02344 *                    Compute A=L*Q
02345 *                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
02346 *
02347                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
02348      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02349 *
02350 *                    Copy L to WORK(IR), zeroing out above it
02351 *
02352                      CALL DLACPY( 'L', M, M, A, LDA, WORK( IR ),
02353      $                            LDWRKR )
02354                      CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
02355      $                            WORK( IR+LDWRKR ), LDWRKR )
02356 *
02357 *                    Generate Q in A
02358 *                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
02359 *
02360                      CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
02361      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02362                      IE = ITAU
02363                      ITAUQ = IE + M
02364                      ITAUP = ITAUQ + M
02365                      IWORK = ITAUP + M
02366 *
02367 *                    Bidiagonalize L in WORK(IR)
02368 *                    (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
02369 *
02370                      CALL DGEBRD( M, M, WORK( IR ), LDWRKR, S,
02371      $                            WORK( IE ), WORK( ITAUQ ),
02372      $                            WORK( ITAUP ), WORK( IWORK ),
02373      $                            LWORK-IWORK+1, IERR )
02374 *
02375 *                    Generate right vectors bidiagonalizing L in
02376 *                    WORK(IR)
02377 *                    (Workspace: need M*M+4*M, prefer M*M+3*M+(M-1)*NB)
02378 *
02379                      CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
02380      $                            WORK( ITAUP ), WORK( IWORK ),
02381      $                            LWORK-IWORK+1, IERR )
02382                      IWORK = IE + M
02383 *
02384 *                    Perform bidiagonal QR iteration, computing right
02385 *                    singular vectors of L in WORK(IR)
02386 *                    (Workspace: need M*M+BDSPAC)
02387 *
02388                      CALL DBDSQR( 'U', M, M, 0, 0, S, WORK( IE ),
02389      $                            WORK( IR ), LDWRKR, DUM, 1, DUM, 1,
02390      $                            WORK( IWORK ), INFO )
02391 *
02392 *                    Multiply right singular vectors of L in WORK(IR) by
02393 *                    Q in A, storing result in VT
02394 *                    (Workspace: need M*M)
02395 *
02396                      CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IR ),
02397      $                           LDWRKR, A, LDA, ZERO, VT, LDVT )
02398 *
02399                   ELSE
02400 *
02401 *                    Insufficient workspace for a fast algorithm
02402 *
02403                      ITAU = 1
02404                      IWORK = ITAU + M
02405 *
02406 *                    Compute A=L*Q
02407 *                    (Workspace: need 2*M, prefer M+M*NB)
02408 *
02409                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
02410      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02411 *
02412 *                    Copy result to VT
02413 *
02414                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
02415 *
02416 *                    Generate Q in VT
02417 *                    (Workspace: need 2*M, prefer M+M*NB)
02418 *
02419                      CALL DORGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
02420      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02421                      IE = ITAU
02422                      ITAUQ = IE + M
02423                      ITAUP = ITAUQ + M
02424                      IWORK = ITAUP + M
02425 *
02426 *                    Zero out above L in A
02427 *
02428                      CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),
02429      $                            LDA )
02430 *
02431 *                    Bidiagonalize L in A
02432 *                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
02433 *
02434                      CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),
02435      $                            WORK( ITAUQ ), WORK( ITAUP ),
02436      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02437 *
02438 *                    Multiply right vectors bidiagonalizing L by Q in VT
02439 *                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
02440 *
02441                      CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,
02442      $                            WORK( ITAUP ), VT, LDVT,
02443      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02444                      IWORK = IE + M
02445 *
02446 *                    Perform bidiagonal QR iteration, computing right
02447 *                    singular vectors of A in VT
02448 *                    (Workspace: need BDSPAC)
02449 *
02450                      CALL DBDSQR( 'U', M, N, 0, 0, S, WORK( IE ), VT,
02451      $                            LDVT, DUM, 1, DUM, 1, WORK( IWORK ),
02452      $                            INFO )
02453 *
02454                   END IF
02455 *
02456                ELSE IF( WNTUO ) THEN
02457 *
02458 *                 Path 5t(N much larger than M, JOBU='O', JOBVT='S')
02459 *                 M right singular vectors to be computed in VT and
02460 *                 M left singular vectors to be overwritten on A
02461 *
02462                   IF( LWORK.GE.2*M*M+MAX( 4*M, BDSPAC ) ) THEN
02463 *
02464 *                    Sufficient workspace for a fast algorithm
02465 *
02466                      IU = 1
02467                      IF( LWORK.GE.WRKBL+2*LDA*M ) THEN
02468 *
02469 *                       WORK(IU) is LDA by M and WORK(IR) is LDA by M
02470 *
02471                         LDWRKU = LDA
02472                         IR = IU + LDWRKU*M
02473                         LDWRKR = LDA
02474                      ELSE IF( LWORK.GE.WRKBL+( LDA+M )*M ) THEN
02475 *
02476 *                       WORK(IU) is LDA by M and WORK(IR) is M by M
02477 *
02478                         LDWRKU = LDA
02479                         IR = IU + LDWRKU*M
02480                         LDWRKR = M
02481                      ELSE
02482 *
02483 *                       WORK(IU) is M by M and WORK(IR) is M by M
02484 *
02485                         LDWRKU = M
02486                         IR = IU + LDWRKU*M
02487                         LDWRKR = M
02488                      END IF
02489                      ITAU = IR + LDWRKR*M
02490                      IWORK = ITAU + M
02491 *
02492 *                    Compute A=L*Q
02493 *                    (Workspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)
02494 *
02495                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
02496      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02497 *
02498 *                    Copy L to WORK(IU), zeroing out below it
02499 *
02500                      CALL DLACPY( 'L', M, M, A, LDA, WORK( IU ),
02501      $                            LDWRKU )
02502                      CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
02503      $                            WORK( IU+LDWRKU ), LDWRKU )
02504 *
02505 *                    Generate Q in A
02506 *                    (Workspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)
02507 *
02508                      CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
02509      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02510                      IE = ITAU
02511                      ITAUQ = IE + M
02512                      ITAUP = ITAUQ + M
02513                      IWORK = ITAUP + M
02514 *
02515 *                    Bidiagonalize L in WORK(IU), copying result to
02516 *                    WORK(IR)
02517 *                    (Workspace: need 2*M*M+4*M,
02518 *                                prefer 2*M*M+3*M+2*M*NB)
02519 *
02520                      CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,
02521      $                            WORK( IE ), WORK( ITAUQ ),
02522      $                            WORK( ITAUP ), WORK( IWORK ),
02523      $                            LWORK-IWORK+1, IERR )
02524                      CALL DLACPY( 'L', M, M, WORK( IU ), LDWRKU,
02525      $                            WORK( IR ), LDWRKR )
02526 *
02527 *                    Generate right bidiagonalizing vectors in WORK(IU)
02528 *                    (Workspace: need 2*M*M+4*M-1,
02529 *                                prefer 2*M*M+3*M+(M-1)*NB)
02530 *
02531                      CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
02532      $                            WORK( ITAUP ), WORK( IWORK ),
02533      $                            LWORK-IWORK+1, IERR )
02534 *
02535 *                    Generate left bidiagonalizing vectors in WORK(IR)
02536 *                    (Workspace: need 2*M*M+4*M, prefer 2*M*M+3*M+M*NB)
02537 *
02538                      CALL DORGBR( 'Q', M, M, M, WORK( IR ), LDWRKR,
02539      $                            WORK( ITAUQ ), WORK( IWORK ),
02540      $                            LWORK-IWORK+1, IERR )
02541                      IWORK = IE + M
02542 *
02543 *                    Perform bidiagonal QR iteration, computing left
02544 *                    singular vectors of L in WORK(IR) and computing
02545 *                    right singular vectors of L in WORK(IU)
02546 *                    (Workspace: need 2*M*M+BDSPAC)
02547 *
02548                      CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
02549      $                            WORK( IU ), LDWRKU, WORK( IR ),
02550      $                            LDWRKR, DUM, 1, WORK( IWORK ), INFO )
02551 *
02552 *                    Multiply right singular vectors of L in WORK(IU) by
02553 *                    Q in A, storing result in VT
02554 *                    (Workspace: need M*M)
02555 *
02556                      CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),
02557      $                           LDWRKU, A, LDA, ZERO, VT, LDVT )
02558 *
02559 *                    Copy left singular vectors of L to A
02560 *                    (Workspace: need M*M)
02561 *
02562                      CALL DLACPY( 'F', M, M, WORK( IR ), LDWRKR, A,
02563      $                            LDA )
02564 *
02565                   ELSE
02566 *
02567 *                    Insufficient workspace for a fast algorithm
02568 *
02569                      ITAU = 1
02570                      IWORK = ITAU + M
02571 *
02572 *                    Compute A=L*Q, copying result to VT
02573 *                    (Workspace: need 2*M, prefer M+M*NB)
02574 *
02575                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
02576      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02577                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
02578 *
02579 *                    Generate Q in VT
02580 *                    (Workspace: need 2*M, prefer M+M*NB)
02581 *
02582                      CALL DORGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
02583      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02584                      IE = ITAU
02585                      ITAUQ = IE + M
02586                      ITAUP = ITAUQ + M
02587                      IWORK = ITAUP + M
02588 *
02589 *                    Zero out above L in A
02590 *
02591                      CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),
02592      $                            LDA )
02593 *
02594 *                    Bidiagonalize L in A
02595 *                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
02596 *
02597                      CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),
02598      $                            WORK( ITAUQ ), WORK( ITAUP ),
02599      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02600 *
02601 *                    Multiply right vectors bidiagonalizing L by Q in VT
02602 *                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
02603 *
02604                      CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,
02605      $                            WORK( ITAUP ), VT, LDVT,
02606      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02607 *
02608 *                    Generate left bidiagonalizing vectors of L in A
02609 *                    (Workspace: need 4*M, prefer 3*M+M*NB)
02610 *
02611                      CALL DORGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
02612      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02613                      IWORK = IE + M
02614 *
02615 *                    Perform bidiagonal QR iteration, compute left
02616 *                    singular vectors of A in A and compute right
02617 *                    singular vectors of A in VT
02618 *                    (Workspace: need BDSPAC)
02619 *
02620                      CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,
02621      $                            LDVT, A, LDA, DUM, 1, WORK( IWORK ),
02622      $                            INFO )
02623 *
02624                   END IF
02625 *
02626                ELSE IF( WNTUAS ) THEN
02627 *
02628 *                 Path 6t(N much larger than M, JOBU='S' or 'A',
02629 *                         JOBVT='S')
02630 *                 M right singular vectors to be computed in VT and
02631 *                 M left singular vectors to be computed in U
02632 *
02633                   IF( LWORK.GE.M*M+MAX( 4*M, BDSPAC ) ) THEN
02634 *
02635 *                    Sufficient workspace for a fast algorithm
02636 *
02637                      IU = 1
02638                      IF( LWORK.GE.WRKBL+LDA*M ) THEN
02639 *
02640 *                       WORK(IU) is LDA by N
02641 *
02642                         LDWRKU = LDA
02643                      ELSE
02644 *
02645 *                       WORK(IU) is LDA by M
02646 *
02647                         LDWRKU = M
02648                      END IF
02649                      ITAU = IU + LDWRKU*M
02650                      IWORK = ITAU + M
02651 *
02652 *                    Compute A=L*Q
02653 *                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
02654 *
02655                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
02656      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02657 *
02658 *                    Copy L to WORK(IU), zeroing out above it
02659 *
02660                      CALL DLACPY( 'L', M, M, A, LDA, WORK( IU ),
02661      $                            LDWRKU )
02662                      CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
02663      $                            WORK( IU+LDWRKU ), LDWRKU )
02664 *
02665 *                    Generate Q in A
02666 *                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
02667 *
02668                      CALL DORGLQ( M, N, M, A, LDA, WORK( ITAU ),
02669      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02670                      IE = ITAU
02671                      ITAUQ = IE + M
02672                      ITAUP = ITAUQ + M
02673                      IWORK = ITAUP + M
02674 *
02675 *                    Bidiagonalize L in WORK(IU), copying result to U
02676 *                    (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
02677 *
02678                      CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,
02679      $                            WORK( IE ), WORK( ITAUQ ),
02680      $                            WORK( ITAUP ), WORK( IWORK ),
02681      $                            LWORK-IWORK+1, IERR )
02682                      CALL DLACPY( 'L', M, M, WORK( IU ), LDWRKU, U,
02683      $                            LDU )
02684 *
02685 *                    Generate right bidiagonalizing vectors in WORK(IU)
02686 *                    (Workspace: need M*M+4*M-1,
02687 *                                prefer M*M+3*M+(M-1)*NB)
02688 *
02689                      CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
02690      $                            WORK( ITAUP ), WORK( IWORK ),
02691      $                            LWORK-IWORK+1, IERR )
02692 *
02693 *                    Generate left bidiagonalizing vectors in U
02694 *                    (Workspace: need M*M+4*M, prefer M*M+3*M+M*NB)
02695 *
02696                      CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
02697      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02698                      IWORK = IE + M
02699 *
02700 *                    Perform bidiagonal QR iteration, computing left
02701 *                    singular vectors of L in U and computing right
02702 *                    singular vectors of L in WORK(IU)
02703 *                    (Workspace: need M*M+BDSPAC)
02704 *
02705                      CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
02706      $                            WORK( IU ), LDWRKU, U, LDU, DUM, 1,
02707      $                            WORK( IWORK ), INFO )
02708 *
02709 *                    Multiply right singular vectors of L in WORK(IU) by
02710 *                    Q in A, storing result in VT
02711 *                    (Workspace: need M*M)
02712 *
02713                      CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),
02714      $                           LDWRKU, A, LDA, ZERO, VT, LDVT )
02715 *
02716                   ELSE
02717 *
02718 *                    Insufficient workspace for a fast algorithm
02719 *
02720                      ITAU = 1
02721                      IWORK = ITAU + M
02722 *
02723 *                    Compute A=L*Q, copying result to VT
02724 *                    (Workspace: need 2*M, prefer M+M*NB)
02725 *
02726                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
02727      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02728                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
02729 *
02730 *                    Generate Q in VT
02731 *                    (Workspace: need 2*M, prefer M+M*NB)
02732 *
02733                      CALL DORGLQ( M, N, M, VT, LDVT, WORK( ITAU ),
02734      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02735 *
02736 *                    Copy L to U, zeroing out above it
02737 *
02738                      CALL DLACPY( 'L', M, M, A, LDA, U, LDU )
02739                      CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),
02740      $                            LDU )
02741                      IE = ITAU
02742                      ITAUQ = IE + M
02743                      ITAUP = ITAUQ + M
02744                      IWORK = ITAUP + M
02745 *
02746 *                    Bidiagonalize L in U
02747 *                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
02748 *
02749                      CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),
02750      $                            WORK( ITAUQ ), WORK( ITAUP ),
02751      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02752 *
02753 *                    Multiply right bidiagonalizing vectors in U by Q
02754 *                    in VT
02755 *                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
02756 *
02757                      CALL DORMBR( 'P', 'L', 'T', M, N, M, U, LDU,
02758      $                            WORK( ITAUP ), VT, LDVT,
02759      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02760 *
02761 *                    Generate left bidiagonalizing vectors in U
02762 *                    (Workspace: need 4*M, prefer 3*M+M*NB)
02763 *
02764                      CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
02765      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02766                      IWORK = IE + M
02767 *
02768 *                    Perform bidiagonal QR iteration, computing left
02769 *                    singular vectors of A in U and computing right
02770 *                    singular vectors of A in VT
02771 *                    (Workspace: need BDSPAC)
02772 *
02773                      CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,
02774      $                            LDVT, U, LDU, DUM, 1, WORK( IWORK ),
02775      $                            INFO )
02776 *
02777                   END IF
02778 *
02779                END IF
02780 *
02781             ELSE IF( WNTVA ) THEN
02782 *
02783                IF( WNTUN ) THEN
02784 *
02785 *                 Path 7t(N much larger than M, JOBU='N', JOBVT='A')
02786 *                 N right singular vectors to be computed in VT and
02787 *                 no left singular vectors to be computed
02788 *
02789                   IF( LWORK.GE.M*M+MAX( N+M, 4*M, BDSPAC ) ) THEN
02790 *
02791 *                    Sufficient workspace for a fast algorithm
02792 *
02793                      IR = 1
02794                      IF( LWORK.GE.WRKBL+LDA*M ) THEN
02795 *
02796 *                       WORK(IR) is LDA by M
02797 *
02798                         LDWRKR = LDA
02799                      ELSE
02800 *
02801 *                       WORK(IR) is M by M
02802 *
02803                         LDWRKR = M
02804                      END IF
02805                      ITAU = IR + LDWRKR*M
02806                      IWORK = ITAU + M
02807 *
02808 *                    Compute A=L*Q, copying result to VT
02809 *                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
02810 *
02811                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
02812      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02813                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
02814 *
02815 *                    Copy L to WORK(IR), zeroing out above it
02816 *
02817                      CALL DLACPY( 'L', M, M, A, LDA, WORK( IR ),
02818      $                            LDWRKR )
02819                      CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
02820      $                            WORK( IR+LDWRKR ), LDWRKR )
02821 *
02822 *                    Generate Q in VT
02823 *                    (Workspace: need M*M+M+N, prefer M*M+M+N*NB)
02824 *
02825                      CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
02826      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02827                      IE = ITAU
02828                      ITAUQ = IE + M
02829                      ITAUP = ITAUQ + M
02830                      IWORK = ITAUP + M
02831 *
02832 *                    Bidiagonalize L in WORK(IR)
02833 *                    (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
02834 *
02835                      CALL DGEBRD( M, M, WORK( IR ), LDWRKR, S,
02836      $                            WORK( IE ), WORK( ITAUQ ),
02837      $                            WORK( ITAUP ), WORK( IWORK ),
02838      $                            LWORK-IWORK+1, IERR )
02839 *
02840 *                    Generate right bidiagonalizing vectors in WORK(IR)
02841 *                    (Workspace: need M*M+4*M-1,
02842 *                                prefer M*M+3*M+(M-1)*NB)
02843 *
02844                      CALL DORGBR( 'P', M, M, M, WORK( IR ), LDWRKR,
02845      $                            WORK( ITAUP ), WORK( IWORK ),
02846      $                            LWORK-IWORK+1, IERR )
02847                      IWORK = IE + M
02848 *
02849 *                    Perform bidiagonal QR iteration, computing right
02850 *                    singular vectors of L in WORK(IR)
02851 *                    (Workspace: need M*M+BDSPAC)
02852 *
02853                      CALL DBDSQR( 'U', M, M, 0, 0, S, WORK( IE ),
02854      $                            WORK( IR ), LDWRKR, DUM, 1, DUM, 1,
02855      $                            WORK( IWORK ), INFO )
02856 *
02857 *                    Multiply right singular vectors of L in WORK(IR) by
02858 *                    Q in VT, storing result in A
02859 *                    (Workspace: need M*M)
02860 *
02861                      CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IR ),
02862      $                           LDWRKR, VT, LDVT, ZERO, A, LDA )
02863 *
02864 *                    Copy right singular vectors of A from A to VT
02865 *
02866                      CALL DLACPY( 'F', M, N, A, LDA, VT, LDVT )
02867 *
02868                   ELSE
02869 *
02870 *                    Insufficient workspace for a fast algorithm
02871 *
02872                      ITAU = 1
02873                      IWORK = ITAU + M
02874 *
02875 *                    Compute A=L*Q, copying result to VT
02876 *                    (Workspace: need 2*M, prefer M+M*NB)
02877 *
02878                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
02879      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02880                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
02881 *
02882 *                    Generate Q in VT
02883 *                    (Workspace: need M+N, prefer M+N*NB)
02884 *
02885                      CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
02886      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02887                      IE = ITAU
02888                      ITAUQ = IE + M
02889                      ITAUP = ITAUQ + M
02890                      IWORK = ITAUP + M
02891 *
02892 *                    Zero out above L in A
02893 *
02894                      CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),
02895      $                            LDA )
02896 *
02897 *                    Bidiagonalize L in A
02898 *                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
02899 *
02900                      CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),
02901      $                            WORK( ITAUQ ), WORK( ITAUP ),
02902      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02903 *
02904 *                    Multiply right bidiagonalizing vectors in A by Q
02905 *                    in VT
02906 *                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
02907 *
02908                      CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,
02909      $                            WORK( ITAUP ), VT, LDVT,
02910      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02911                      IWORK = IE + M
02912 *
02913 *                    Perform bidiagonal QR iteration, computing right
02914 *                    singular vectors of A in VT
02915 *                    (Workspace: need BDSPAC)
02916 *
02917                      CALL DBDSQR( 'U', M, N, 0, 0, S, WORK( IE ), VT,
02918      $                            LDVT, DUM, 1, DUM, 1, WORK( IWORK ),
02919      $                            INFO )
02920 *
02921                   END IF
02922 *
02923                ELSE IF( WNTUO ) THEN
02924 *
02925 *                 Path 8t(N much larger than M, JOBU='O', JOBVT='A')
02926 *                 N right singular vectors to be computed in VT and
02927 *                 M left singular vectors to be overwritten on A
02928 *
02929                   IF( LWORK.GE.2*M*M+MAX( N+M, 4*M, BDSPAC ) ) THEN
02930 *
02931 *                    Sufficient workspace for a fast algorithm
02932 *
02933                      IU = 1
02934                      IF( LWORK.GE.WRKBL+2*LDA*M ) THEN
02935 *
02936 *                       WORK(IU) is LDA by M and WORK(IR) is LDA by M
02937 *
02938                         LDWRKU = LDA
02939                         IR = IU + LDWRKU*M
02940                         LDWRKR = LDA
02941                      ELSE IF( LWORK.GE.WRKBL+( LDA+M )*M ) THEN
02942 *
02943 *                       WORK(IU) is LDA by M and WORK(IR) is M by M
02944 *
02945                         LDWRKU = LDA
02946                         IR = IU + LDWRKU*M
02947                         LDWRKR = M
02948                      ELSE
02949 *
02950 *                       WORK(IU) is M by M and WORK(IR) is M by M
02951 *
02952                         LDWRKU = M
02953                         IR = IU + LDWRKU*M
02954                         LDWRKR = M
02955                      END IF
02956                      ITAU = IR + LDWRKR*M
02957                      IWORK = ITAU + M
02958 *
02959 *                    Compute A=L*Q, copying result to VT
02960 *                    (Workspace: need 2*M*M+2*M, prefer 2*M*M+M+M*NB)
02961 *
02962                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
02963      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02964                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
02965 *
02966 *                    Generate Q in VT
02967 *                    (Workspace: need 2*M*M+M+N, prefer 2*M*M+M+N*NB)
02968 *
02969                      CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
02970      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
02971 *
02972 *                    Copy L to WORK(IU), zeroing out above it
02973 *
02974                      CALL DLACPY( 'L', M, M, A, LDA, WORK( IU ),
02975      $                            LDWRKU )
02976                      CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
02977      $                            WORK( IU+LDWRKU ), LDWRKU )
02978                      IE = ITAU
02979                      ITAUQ = IE + M
02980                      ITAUP = ITAUQ + M
02981                      IWORK = ITAUP + M
02982 *
02983 *                    Bidiagonalize L in WORK(IU), copying result to
02984 *                    WORK(IR)
02985 *                    (Workspace: need 2*M*M+4*M,
02986 *                                prefer 2*M*M+3*M+2*M*NB)
02987 *
02988                      CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,
02989      $                            WORK( IE ), WORK( ITAUQ ),
02990      $                            WORK( ITAUP ), WORK( IWORK ),
02991      $                            LWORK-IWORK+1, IERR )
02992                      CALL DLACPY( 'L', M, M, WORK( IU ), LDWRKU,
02993      $                            WORK( IR ), LDWRKR )
02994 *
02995 *                    Generate right bidiagonalizing vectors in WORK(IU)
02996 *                    (Workspace: need 2*M*M+4*M-1,
02997 *                                prefer 2*M*M+3*M+(M-1)*NB)
02998 *
02999                      CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
03000      $                            WORK( ITAUP ), WORK( IWORK ),
03001      $                            LWORK-IWORK+1, IERR )
03002 *
03003 *                    Generate left bidiagonalizing vectors in WORK(IR)
03004 *                    (Workspace: need 2*M*M+4*M, prefer 2*M*M+3*M+M*NB)
03005 *
03006                      CALL DORGBR( 'Q', M, M, M, WORK( IR ), LDWRKR,
03007      $                            WORK( ITAUQ ), WORK( IWORK ),
03008      $                            LWORK-IWORK+1, IERR )
03009                      IWORK = IE + M
03010 *
03011 *                    Perform bidiagonal QR iteration, computing left
03012 *                    singular vectors of L in WORK(IR) and computing
03013 *                    right singular vectors of L in WORK(IU)
03014 *                    (Workspace: need 2*M*M+BDSPAC)
03015 *
03016                      CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
03017      $                            WORK( IU ), LDWRKU, WORK( IR ),
03018      $                            LDWRKR, DUM, 1, WORK( IWORK ), INFO )
03019 *
03020 *                    Multiply right singular vectors of L in WORK(IU) by
03021 *                    Q in VT, storing result in A
03022 *                    (Workspace: need M*M)
03023 *
03024                      CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),
03025      $                           LDWRKU, VT, LDVT, ZERO, A, LDA )
03026 *
03027 *                    Copy right singular vectors of A from A to VT
03028 *
03029                      CALL DLACPY( 'F', M, N, A, LDA, VT, LDVT )
03030 *
03031 *                    Copy left singular vectors of A from WORK(IR) to A
03032 *
03033                      CALL DLACPY( 'F', M, M, WORK( IR ), LDWRKR, A,
03034      $                            LDA )
03035 *
03036                   ELSE
03037 *
03038 *                    Insufficient workspace for a fast algorithm
03039 *
03040                      ITAU = 1
03041                      IWORK = ITAU + M
03042 *
03043 *                    Compute A=L*Q, copying result to VT
03044 *                    (Workspace: need 2*M, prefer M+M*NB)
03045 *
03046                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
03047      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
03048                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
03049 *
03050 *                    Generate Q in VT
03051 *                    (Workspace: need M+N, prefer M+N*NB)
03052 *
03053                      CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
03054      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
03055                      IE = ITAU
03056                      ITAUQ = IE + M
03057                      ITAUP = ITAUQ + M
03058                      IWORK = ITAUP + M
03059 *
03060 *                    Zero out above L in A
03061 *
03062                      CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, A( 1, 2 ),
03063      $                            LDA )
03064 *
03065 *                    Bidiagonalize L in A
03066 *                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
03067 *
03068                      CALL DGEBRD( M, M, A, LDA, S, WORK( IE ),
03069      $                            WORK( ITAUQ ), WORK( ITAUP ),
03070      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
03071 *
03072 *                    Multiply right bidiagonalizing vectors in A by Q
03073 *                    in VT
03074 *                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
03075 *
03076                      CALL DORMBR( 'P', 'L', 'T', M, N, M, A, LDA,
03077      $                            WORK( ITAUP ), VT, LDVT,
03078      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
03079 *
03080 *                    Generate left bidiagonalizing vectors in A
03081 *                    (Workspace: need 4*M, prefer 3*M+M*NB)
03082 *
03083                      CALL DORGBR( 'Q', M, M, M, A, LDA, WORK( ITAUQ ),
03084      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
03085                      IWORK = IE + M
03086 *
03087 *                    Perform bidiagonal QR iteration, computing left
03088 *                    singular vectors of A in A and computing right
03089 *                    singular vectors of A in VT
03090 *                    (Workspace: need BDSPAC)
03091 *
03092                      CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,
03093      $                            LDVT, A, LDA, DUM, 1, WORK( IWORK ),
03094      $                            INFO )
03095 *
03096                   END IF
03097 *
03098                ELSE IF( WNTUAS ) THEN
03099 *
03100 *                 Path 9t(N much larger than M, JOBU='S' or 'A',
03101 *                         JOBVT='A')
03102 *                 N right singular vectors to be computed in VT and
03103 *                 M left singular vectors to be computed in U
03104 *
03105                   IF( LWORK.GE.M*M+MAX( N+M, 4*M, BDSPAC ) ) THEN
03106 *
03107 *                    Sufficient workspace for a fast algorithm
03108 *
03109                      IU = 1
03110                      IF( LWORK.GE.WRKBL+LDA*M ) THEN
03111 *
03112 *                       WORK(IU) is LDA by M
03113 *
03114                         LDWRKU = LDA
03115                      ELSE
03116 *
03117 *                       WORK(IU) is M by M
03118 *
03119                         LDWRKU = M
03120                      END IF
03121                      ITAU = IU + LDWRKU*M
03122                      IWORK = ITAU + M
03123 *
03124 *                    Compute A=L*Q, copying result to VT
03125 *                    (Workspace: need M*M+2*M, prefer M*M+M+M*NB)
03126 *
03127                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
03128      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
03129                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
03130 *
03131 *                    Generate Q in VT
03132 *                    (Workspace: need M*M+M+N, prefer M*M+M+N*NB)
03133 *
03134                      CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
03135      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
03136 *
03137 *                    Copy L to WORK(IU), zeroing out above it
03138 *
03139                      CALL DLACPY( 'L', M, M, A, LDA, WORK( IU ),
03140      $                            LDWRKU )
03141                      CALL DLASET( 'U', M-1, M-1, ZERO, ZERO,
03142      $                            WORK( IU+LDWRKU ), LDWRKU )
03143                      IE = ITAU
03144                      ITAUQ = IE + M
03145                      ITAUP = ITAUQ + M
03146                      IWORK = ITAUP + M
03147 *
03148 *                    Bidiagonalize L in WORK(IU), copying result to U
03149 *                    (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB)
03150 *
03151                      CALL DGEBRD( M, M, WORK( IU ), LDWRKU, S,
03152      $                            WORK( IE ), WORK( ITAUQ ),
03153      $                            WORK( ITAUP ), WORK( IWORK ),
03154      $                            LWORK-IWORK+1, IERR )
03155                      CALL DLACPY( 'L', M, M, WORK( IU ), LDWRKU, U,
03156      $                            LDU )
03157 *
03158 *                    Generate right bidiagonalizing vectors in WORK(IU)
03159 *                    (Workspace: need M*M+4*M, prefer M*M+3*M+(M-1)*NB)
03160 *
03161                      CALL DORGBR( 'P', M, M, M, WORK( IU ), LDWRKU,
03162      $                            WORK( ITAUP ), WORK( IWORK ),
03163      $                            LWORK-IWORK+1, IERR )
03164 *
03165 *                    Generate left bidiagonalizing vectors in U
03166 *                    (Workspace: need M*M+4*M, prefer M*M+3*M+M*NB)
03167 *
03168                      CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
03169      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
03170                      IWORK = IE + M
03171 *
03172 *                    Perform bidiagonal QR iteration, computing left
03173 *                    singular vectors of L in U and computing right
03174 *                    singular vectors of L in WORK(IU)
03175 *                    (Workspace: need M*M+BDSPAC)
03176 *
03177                      CALL DBDSQR( 'U', M, M, M, 0, S, WORK( IE ),
03178      $                            WORK( IU ), LDWRKU, U, LDU, DUM, 1,
03179      $                            WORK( IWORK ), INFO )
03180 *
03181 *                    Multiply right singular vectors of L in WORK(IU) by
03182 *                    Q in VT, storing result in A
03183 *                    (Workspace: need M*M)
03184 *
03185                      CALL DGEMM( 'N', 'N', M, N, M, ONE, WORK( IU ),
03186      $                           LDWRKU, VT, LDVT, ZERO, A, LDA )
03187 *
03188 *                    Copy right singular vectors of A from A to VT
03189 *
03190                      CALL DLACPY( 'F', M, N, A, LDA, VT, LDVT )
03191 *
03192                   ELSE
03193 *
03194 *                    Insufficient workspace for a fast algorithm
03195 *
03196                      ITAU = 1
03197                      IWORK = ITAU + M
03198 *
03199 *                    Compute A=L*Q, copying result to VT
03200 *                    (Workspace: need 2*M, prefer M+M*NB)
03201 *
03202                      CALL DGELQF( M, N, A, LDA, WORK( ITAU ),
03203      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
03204                      CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
03205 *
03206 *                    Generate Q in VT
03207 *                    (Workspace: need M+N, prefer M+N*NB)
03208 *
03209                      CALL DORGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
03210      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
03211 *
03212 *                    Copy L to U, zeroing out above it
03213 *
03214                      CALL DLACPY( 'L', M, M, A, LDA, U, LDU )
03215                      CALL DLASET( 'U', M-1, M-1, ZERO, ZERO, U( 1, 2 ),
03216      $                            LDU )
03217                      IE = ITAU
03218                      ITAUQ = IE + M
03219                      ITAUP = ITAUQ + M
03220                      IWORK = ITAUP + M
03221 *
03222 *                    Bidiagonalize L in U
03223 *                    (Workspace: need 4*M, prefer 3*M+2*M*NB)
03224 *
03225                      CALL DGEBRD( M, M, U, LDU, S, WORK( IE ),
03226      $                            WORK( ITAUQ ), WORK( ITAUP ),
03227      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
03228 *
03229 *                    Multiply right bidiagonalizing vectors in U by Q
03230 *                    in VT
03231 *                    (Workspace: need 3*M+N, prefer 3*M+N*NB)
03232 *
03233                      CALL DORMBR( 'P', 'L', 'T', M, N, M, U, LDU,
03234      $                            WORK( ITAUP ), VT, LDVT,
03235      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
03236 *
03237 *                    Generate left bidiagonalizing vectors in U
03238 *                    (Workspace: need 4*M, prefer 3*M+M*NB)
03239 *
03240                      CALL DORGBR( 'Q', M, M, M, U, LDU, WORK( ITAUQ ),
03241      $                            WORK( IWORK ), LWORK-IWORK+1, IERR )
03242                      IWORK = IE + M
03243 *
03244 *                    Perform bidiagonal QR iteration, computing left
03245 *                    singular vectors of A in U and computing right
03246 *                    singular vectors of A in VT
03247 *                    (Workspace: need BDSPAC)
03248 *
03249                      CALL DBDSQR( 'U', M, N, M, 0, S, WORK( IE ), VT,
03250      $                            LDVT, U, LDU, DUM, 1, WORK( IWORK ),
03251      $                            INFO )
03252 *
03253                   END IF
03254 *
03255                END IF
03256 *
03257             END IF
03258 *
03259          ELSE
03260 *
03261 *           N .LT. MNTHR
03262 *
03263 *           Path 10t(N greater than M, but not much larger)
03264 *           Reduce to bidiagonal form without LQ decomposition
03265 *
03266             IE = 1
03267             ITAUQ = IE + M
03268             ITAUP = ITAUQ + M
03269             IWORK = ITAUP + M
03270 *
03271 *           Bidiagonalize A
03272 *           (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB)
03273 *
03274             CALL DGEBRD( M, N, A, LDA, S, WORK( IE ), WORK( ITAUQ ),
03275      $                   WORK( ITAUP ), WORK( IWORK ), LWORK-IWORK+1,
03276      $                   IERR )
03277             IF( WNTUAS ) THEN
03278 *
03279 *              If left singular vectors desired in U, copy result to U
03280 *              and generate left bidiagonalizing vectors in U
03281 *              (Workspace: need 4*M-1, prefer 3*M+(M-1)*NB)
03282 *
03283                CALL DLACPY( 'L', M, M, A, LDA, U, LDU )
03284                CALL DORGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
03285      $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
03286             END IF
03287             IF( WNTVAS ) THEN
03288 *
03289 *              If right singular vectors desired in VT, copy result to
03290 *              VT and generate right bidiagonalizing vectors in VT
03291 *              (Workspace: need 3*M+NRVT, prefer 3*M+NRVT*NB)
03292 *
03293                CALL DLACPY( 'U', M, N, A, LDA, VT, LDVT )
03294                IF( WNTVA )
03295      $            NRVT = N
03296                IF( WNTVS )
03297      $            NRVT = M
03298                CALL DORGBR( 'P', NRVT, N, M, VT, LDVT, WORK( ITAUP ),
03299      $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
03300             END IF
03301             IF( WNTUO ) THEN
03302 *
03303 *              If left singular vectors desired in A, generate left
03304 *              bidiagonalizing vectors in A
03305 *              (Workspace: need 4*M-1, prefer 3*M+(M-1)*NB)
03306 *
03307                CALL DORGBR( 'Q', M, M, N, A, LDA, WORK( ITAUQ ),
03308      $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
03309             END IF
03310             IF( WNTVO ) THEN
03311 *
03312 *              If right singular vectors desired in A, generate right
03313 *              bidiagonalizing vectors in A
03314 *              (Workspace: need 4*M, prefer 3*M+M*NB)
03315 *
03316                CALL DORGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
03317      $                      WORK( IWORK ), LWORK-IWORK+1, IERR )
03318             END IF
03319             IWORK = IE + M
03320             IF( WNTUAS .OR. WNTUO )
03321      $         NRU = M
03322             IF( WNTUN )
03323      $         NRU = 0
03324             IF( WNTVAS .OR. WNTVO )
03325      $         NCVT = N
03326             IF( WNTVN )
03327      $         NCVT = 0
03328             IF( ( .NOT.WNTUO ) .AND. ( .NOT.WNTVO ) ) THEN
03329 *
03330 *              Perform bidiagonal QR iteration, if desired, computing
03331 *              left singular vectors in U and computing right singular
03332 *              vectors in VT
03333 *              (Workspace: need BDSPAC)
03334 *
03335                CALL DBDSQR( 'L', M, NCVT, NRU, 0, S, WORK( IE ), VT,
03336      $                      LDVT, U, LDU, DUM, 1, WORK( IWORK ), INFO )
03337             ELSE IF( ( .NOT.WNTUO ) .AND. WNTVO ) THEN
03338 *
03339 *              Perform bidiagonal QR iteration, if desired, computing
03340 *              left singular vectors in U and computing right singular
03341 *              vectors in A
03342 *              (Workspace: need BDSPAC)
03343 *
03344                CALL DBDSQR( 'L', M, NCVT, NRU, 0, S, WORK( IE ), A, LDA,
03345      $                      U, LDU, DUM, 1, WORK( IWORK ), INFO )
03346             ELSE
03347 *
03348 *              Perform bidiagonal QR iteration, if desired, computing
03349 *              left singular vectors in A and computing right singular
03350 *              vectors in VT
03351 *              (Workspace: need BDSPAC)
03352 *
03353                CALL DBDSQR( 'L', M, NCVT, NRU, 0, S, WORK( IE ), VT,
03354      $                      LDVT, A, LDA, DUM, 1, WORK( IWORK ), INFO )
03355             END IF
03356 *
03357          END IF
03358 *
03359       END IF
03360 *
03361 *     If DBDSQR failed to converge, copy unconverged superdiagonals
03362 *     to WORK( 2:MINMN )
03363 *
03364       IF( INFO.NE.0 ) THEN
03365          IF( IE.GT.2 ) THEN
03366             DO 50 I = 1, MINMN - 1
03367                WORK( I+1 ) = WORK( I+IE-1 )
03368    50       CONTINUE
03369          END IF
03370          IF( IE.LT.2 ) THEN
03371             DO 60 I = MINMN - 1, 1, -1
03372                WORK( I+1 ) = WORK( I+IE-1 )
03373    60       CONTINUE
03374          END IF
03375       END IF
03376 *
03377 *     Undo scaling if necessary
03378 *
03379       IF( ISCL.EQ.1 ) THEN
03380          IF( ANRM.GT.BIGNUM )
03381      $      CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,
03382      $                   IERR )
03383          IF( INFO.NE.0 .AND. ANRM.GT.BIGNUM )
03384      $      CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN-1, 1, WORK( 2 ),
03385      $                   MINMN, IERR )
03386          IF( ANRM.LT.SMLNUM )
03387      $      CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,
03388      $                   IERR )
03389          IF( INFO.NE.0 .AND. ANRM.LT.SMLNUM )
03390      $      CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN-1, 1, WORK( 2 ),
03391      $                   MINMN, IERR )
03392       END IF
03393 *
03394 *     Return optimal workspace in WORK(1)
03395 *
03396       WORK( 1 ) = MAXWRK
03397 *
03398       RETURN
03399 *
03400 *     End of DGESVD
03401 *
03402       END
 All Files Functions