dgesdd.c
Go to the documentation of this file.
00001 /* dgesdd.f -- translated by f2c (version 20061008).
00002    You must link the resulting object file with libf2c:
00003         on Microsoft Windows system, link with libf2c.lib;
00004         on Linux or Unix systems, link with .../path/to/libf2c.a -lm
00005         or, if you install libf2c.a in a standard place, with -lf2c -lm
00006         -- in that order, at the end of the command line, as in
00007                 cc *.o -lf2c -lm
00008         Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
00009 
00010                 http://www.netlib.org/f2c/libf2c.zip
00011 */
00012 
00013 #include "f2c.h"
00014 #include "blaswrap.h"
00015 
00016 /* Table of constant values */
00017 
00018 static integer c__1 = 1;
00019 static integer c_n1 = -1;
00020 static integer c__0 = 0;
00021 static doublereal c_b227 = 0.;
00022 static doublereal c_b248 = 1.;
00023 
00024 /* Subroutine */ int dgesdd_(char *jobz, integer *m, integer *n, doublereal *
00025         a, integer *lda, doublereal *s, doublereal *u, integer *ldu, 
00026         doublereal *vt, integer *ldvt, doublereal *work, integer *lwork, 
00027         integer *iwork, integer *info)
00028 {
00029     /* System generated locals */
00030     integer a_dim1, a_offset, u_dim1, u_offset, vt_dim1, vt_offset, i__1, 
00031             i__2, i__3;
00032 
00033     /* Builtin functions */
00034     double sqrt(doublereal);
00035 
00036     /* Local variables */
00037     integer i__, ie, il, ir, iu, blk;
00038     doublereal dum[1], eps;
00039     integer ivt, iscl;
00040     doublereal anrm;
00041     integer idum[1], ierr, itau;
00042     extern /* Subroutine */ int dgemm_(char *, char *, integer *, integer *, 
00043             integer *, doublereal *, doublereal *, integer *, doublereal *, 
00044             integer *, doublereal *, doublereal *, integer *);
00045     extern logical lsame_(char *, char *);
00046     integer chunk, minmn, wrkbl, itaup, itauq, mnthr;
00047     logical wntqa;
00048     integer nwork;
00049     logical wntqn, wntqo, wntqs;
00050     extern /* Subroutine */ int dbdsdc_(char *, char *, integer *, doublereal 
00051             *, doublereal *, doublereal *, integer *, doublereal *, integer *, 
00052              doublereal *, integer *, doublereal *, integer *, integer *), dgebrd_(integer *, integer *, doublereal *, 
00053             integer *, doublereal *, doublereal *, doublereal *, doublereal *, 
00054              doublereal *, integer *, integer *);
00055     extern doublereal dlamch_(char *), dlange_(char *, integer *, 
00056             integer *, doublereal *, integer *, doublereal *);
00057     integer bdspac;
00058     extern /* Subroutine */ int dgelqf_(integer *, integer *, doublereal *, 
00059             integer *, doublereal *, doublereal *, integer *, integer *), 
00060             dlascl_(char *, integer *, integer *, doublereal *, doublereal *, 
00061             integer *, integer *, doublereal *, integer *, integer *),
00062              dgeqrf_(integer *, integer *, doublereal *, integer *, 
00063             doublereal *, doublereal *, integer *, integer *), dlacpy_(char *, 
00064              integer *, integer *, doublereal *, integer *, doublereal *, 
00065             integer *), dlaset_(char *, integer *, integer *, 
00066             doublereal *, doublereal *, doublereal *, integer *), 
00067             xerbla_(char *, integer *), dorgbr_(char *, integer *, 
00068             integer *, integer *, doublereal *, integer *, doublereal *, 
00069             doublereal *, integer *, integer *);
00070     extern integer ilaenv_(integer *, char *, char *, integer *, integer *, 
00071             integer *, integer *);
00072     doublereal bignum;
00073     extern /* Subroutine */ int dormbr_(char *, char *, char *, integer *, 
00074             integer *, integer *, doublereal *, integer *, doublereal *, 
00075             doublereal *, integer *, doublereal *, integer *, integer *), dorglq_(integer *, integer *, integer *, 
00076             doublereal *, integer *, doublereal *, doublereal *, integer *, 
00077             integer *), dorgqr_(integer *, integer *, integer *, doublereal *, 
00078              integer *, doublereal *, doublereal *, integer *, integer *);
00079     integer ldwrkl, ldwrkr, minwrk, ldwrku, maxwrk, ldwkvt;
00080     doublereal smlnum;
00081     logical wntqas, lquery;
00082 
00083 
00084 /*  -- LAPACK driver routine (version 3.2.1)                                  -- */
00085 /*  -- LAPACK is a software package provided by Univ. of Tennessee,    -- */
00086 /*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */
00087 /*     March 2009 */
00088 
00089 /*     .. Scalar Arguments .. */
00090 /*     .. */
00091 /*     .. Array Arguments .. */
00092 /*     .. */
00093 
00094 /*  Purpose */
00095 /*  ======= */
00096 
00097 /*  DGESDD computes the singular value decomposition (SVD) of a real */
00098 /*  M-by-N matrix A, optionally computing the left and right singular */
00099 /*  vectors.  If singular vectors are desired, it uses a */
00100 /*  divide-and-conquer algorithm. */
00101 
00102 /*  The SVD is written */
00103 
00104 /*       A = U * SIGMA * transpose(V) */
00105 
00106 /*  where SIGMA is an M-by-N matrix which is zero except for its */
00107 /*  min(m,n) diagonal elements, U is an M-by-M orthogonal matrix, and */
00108 /*  V is an N-by-N orthogonal matrix.  The diagonal elements of SIGMA */
00109 /*  are the singular values of A; they are real and non-negative, and */
00110 /*  are returned in descending order.  The first min(m,n) columns of */
00111 /*  U and V are the left and right singular vectors of A. */
00112 
00113 /*  Note that the routine returns VT = V**T, not V. */
00114 
00115 /*  The divide and conquer algorithm makes very mild assumptions about */
00116 /*  floating point arithmetic. It will work on machines with a guard */
00117 /*  digit in add/subtract, or on those binary machines without guard */
00118 /*  digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or */
00119 /*  Cray-2. It could conceivably fail on hexadecimal or decimal machines */
00120 /*  without guard digits, but we know of none. */
00121 
00122 /*  Arguments */
00123 /*  ========= */
00124 
00125 /*  JOBZ    (input) CHARACTER*1 */
00126 /*          Specifies options for computing all or part of the matrix U: */
00127 /*          = 'A':  all M columns of U and all N rows of V**T are */
00128 /*                  returned in the arrays U and VT; */
00129 /*          = 'S':  the first min(M,N) columns of U and the first */
00130 /*                  min(M,N) rows of V**T are returned in the arrays U */
00131 /*                  and VT; */
00132 /*          = 'O':  If M >= N, the first N columns of U are overwritten */
00133 /*                  on the array A and all rows of V**T are returned in */
00134 /*                  the array VT; */
00135 /*                  otherwise, all columns of U are returned in the */
00136 /*                  array U and the first M rows of V**T are overwritten */
00137 /*                  in the array A; */
00138 /*          = 'N':  no columns of U or rows of V**T are computed. */
00139 
00140 /*  M       (input) INTEGER */
00141 /*          The number of rows of the input matrix A.  M >= 0. */
00142 
00143 /*  N       (input) INTEGER */
00144 /*          The number of columns of the input matrix A.  N >= 0. */
00145 
00146 /*  A       (input/output) DOUBLE PRECISION array, dimension (LDA,N) */
00147 /*          On entry, the M-by-N matrix A. */
00148 /*          On exit, */
00149 /*          if JOBZ = 'O',  A is overwritten with the first N columns */
00150 /*                          of U (the left singular vectors, stored */
00151 /*                          columnwise) if M >= N; */
00152 /*                          A is overwritten with the first M rows */
00153 /*                          of V**T (the right singular vectors, stored */
00154 /*                          rowwise) otherwise. */
00155 /*          if JOBZ .ne. 'O', the contents of A are destroyed. */
00156 
00157 /*  LDA     (input) INTEGER */
00158 /*          The leading dimension of the array A.  LDA >= max(1,M). */
00159 
00160 /*  S       (output) DOUBLE PRECISION array, dimension (min(M,N)) */
00161 /*          The singular values of A, sorted so that S(i) >= S(i+1). */
00162 
00163 /*  U       (output) DOUBLE PRECISION array, dimension (LDU,UCOL) */
00164 /*          UCOL = M if JOBZ = 'A' or JOBZ = 'O' and M < N; */
00165 /*          UCOL = min(M,N) if JOBZ = 'S'. */
00166 /*          If JOBZ = 'A' or JOBZ = 'O' and M < N, U contains the M-by-M */
00167 /*          orthogonal matrix U; */
00168 /*          if JOBZ = 'S', U contains the first min(M,N) columns of U */
00169 /*          (the left singular vectors, stored columnwise); */
00170 /*          if JOBZ = 'O' and M >= N, or JOBZ = 'N', U is not referenced. */
00171 
00172 /*  LDU     (input) INTEGER */
00173 /*          The leading dimension of the array U.  LDU >= 1; if */
00174 /*          JOBZ = 'S' or 'A' or JOBZ = 'O' and M < N, LDU >= M. */
00175 
00176 /*  VT      (output) DOUBLE PRECISION array, dimension (LDVT,N) */
00177 /*          If JOBZ = 'A' or JOBZ = 'O' and M >= N, VT contains the */
00178 /*          N-by-N orthogonal matrix V**T; */
00179 /*          if JOBZ = 'S', VT contains the first min(M,N) rows of */
00180 /*          V**T (the right singular vectors, stored rowwise); */
00181 /*          if JOBZ = 'O' and M < N, or JOBZ = 'N', VT is not referenced. */
00182 
00183 /*  LDVT    (input) INTEGER */
00184 /*          The leading dimension of the array VT.  LDVT >= 1; if */
00185 /*          JOBZ = 'A' or JOBZ = 'O' and M >= N, LDVT >= N; */
00186 /*          if JOBZ = 'S', LDVT >= min(M,N). */
00187 
00188 /*  WORK    (workspace/output) DOUBLE PRECISION array, dimension (MAX(1,LWORK)) */
00189 /*          On exit, if INFO = 0, WORK(1) returns the optimal LWORK; */
00190 
00191 /*  LWORK   (input) INTEGER */
00192 /*          The dimension of the array WORK. LWORK >= 1. */
00193 /*          If JOBZ = 'N', */
00194 /*            LWORK >= 3*min(M,N) + max(max(M,N),7*min(M,N)). */
00195 /*          If JOBZ = 'O', */
00196 /*            LWORK >= 3*min(M,N) + */
00197 /*                     max(max(M,N),5*min(M,N)*min(M,N)+4*min(M,N)). */
00198 /*          If JOBZ = 'S' or 'A' */
00199 /*            LWORK >= 3*min(M,N) + */
00200 /*                     max(max(M,N),4*min(M,N)*min(M,N)+4*min(M,N)). */
00201 /*          For good performance, LWORK should generally be larger. */
00202 /*          If LWORK = -1 but other input arguments are legal, WORK(1) */
00203 /*          returns the optimal LWORK. */
00204 
00205 /*  IWORK   (workspace) INTEGER array, dimension (8*min(M,N)) */
00206 
00207 /*  INFO    (output) INTEGER */
00208 /*          = 0:  successful exit. */
00209 /*          < 0:  if INFO = -i, the i-th argument had an illegal value. */
00210 /*          > 0:  DBDSDC did not converge, updating process failed. */
00211 
00212 /*  Further Details */
00213 /*  =============== */
00214 
00215 /*  Based on contributions by */
00216 /*     Ming Gu and Huan Ren, Computer Science Division, University of */
00217 /*     California at Berkeley, USA */
00218 
00219 /*  ===================================================================== */
00220 
00221 /*     .. Parameters .. */
00222 /*     .. */
00223 /*     .. Local Scalars .. */
00224 /*     .. */
00225 /*     .. Local Arrays .. */
00226 /*     .. */
00227 /*     .. External Subroutines .. */
00228 /*     .. */
00229 /*     .. External Functions .. */
00230 /*     .. */
00231 /*     .. Intrinsic Functions .. */
00232 /*     .. */
00233 /*     .. Executable Statements .. */
00234 
00235 /*     Test the input arguments */
00236 
00237     /* Parameter adjustments */
00238     a_dim1 = *lda;
00239     a_offset = 1 + a_dim1;
00240     a -= a_offset;
00241     --s;
00242     u_dim1 = *ldu;
00243     u_offset = 1 + u_dim1;
00244     u -= u_offset;
00245     vt_dim1 = *ldvt;
00246     vt_offset = 1 + vt_dim1;
00247     vt -= vt_offset;
00248     --work;
00249     --iwork;
00250 
00251     /* Function Body */
00252     *info = 0;
00253     minmn = min(*m,*n);
00254     wntqa = lsame_(jobz, "A");
00255     wntqs = lsame_(jobz, "S");
00256     wntqas = wntqa || wntqs;
00257     wntqo = lsame_(jobz, "O");
00258     wntqn = lsame_(jobz, "N");
00259     lquery = *lwork == -1;
00260 
00261     if (! (wntqa || wntqs || wntqo || wntqn)) {
00262         *info = -1;
00263     } else if (*m < 0) {
00264         *info = -2;
00265     } else if (*n < 0) {
00266         *info = -3;
00267     } else if (*lda < max(1,*m)) {
00268         *info = -5;
00269     } else if (*ldu < 1 || wntqas && *ldu < *m || wntqo && *m < *n && *ldu < *
00270             m) {
00271         *info = -8;
00272     } else if (*ldvt < 1 || wntqa && *ldvt < *n || wntqs && *ldvt < minmn || 
00273             wntqo && *m >= *n && *ldvt < *n) {
00274         *info = -10;
00275     }
00276 
00277 /*     Compute workspace */
00278 /*      (Note: Comments in the code beginning "Workspace:" describe the */
00279 /*       minimal amount of workspace needed at that point in the code, */
00280 /*       as well as the preferred amount for good performance. */
00281 /*       NB refers to the optimal block size for the immediately */
00282 /*       following subroutine, as returned by ILAENV.) */
00283 
00284     if (*info == 0) {
00285         minwrk = 1;
00286         maxwrk = 1;
00287         if (*m >= *n && minmn > 0) {
00288 
00289 /*           Compute space needed for DBDSDC */
00290 
00291             mnthr = (integer) (minmn * 11. / 6.);
00292             if (wntqn) {
00293                 bdspac = *n * 7;
00294             } else {
00295                 bdspac = *n * 3 * *n + (*n << 2);
00296             }
00297             if (*m >= mnthr) {
00298                 if (wntqn) {
00299 
00300 /*                 Path 1 (M much larger than N, JOBZ='N') */
00301 
00302                     wrkbl = *n + *n * ilaenv_(&c__1, "DGEQRF", " ", m, n, &
00303                             c_n1, &c_n1);
00304 /* Computing MAX */
00305                     i__1 = wrkbl, i__2 = *n * 3 + (*n << 1) * ilaenv_(&c__1, 
00306                             "DGEBRD", " ", n, n, &c_n1, &c_n1);
00307                     wrkbl = max(i__1,i__2);
00308 /* Computing MAX */
00309                     i__1 = wrkbl, i__2 = bdspac + *n;
00310                     maxwrk = max(i__1,i__2);
00311                     minwrk = bdspac + *n;
00312                 } else if (wntqo) {
00313 
00314 /*                 Path 2 (M much larger than N, JOBZ='O') */
00315 
00316                     wrkbl = *n + *n * ilaenv_(&c__1, "DGEQRF", " ", m, n, &
00317                             c_n1, &c_n1);
00318 /* Computing MAX */
00319                     i__1 = wrkbl, i__2 = *n + *n * ilaenv_(&c__1, "DORGQR", 
00320                             " ", m, n, n, &c_n1);
00321                     wrkbl = max(i__1,i__2);
00322 /* Computing MAX */
00323                     i__1 = wrkbl, i__2 = *n * 3 + (*n << 1) * ilaenv_(&c__1, 
00324                             "DGEBRD", " ", n, n, &c_n1, &c_n1);
00325                     wrkbl = max(i__1,i__2);
00326 /* Computing MAX */
00327                     i__1 = wrkbl, i__2 = *n * 3 + *n * ilaenv_(&c__1, "DORMBR"
00328 , "QLN", n, n, n, &c_n1);
00329                     wrkbl = max(i__1,i__2);
00330 /* Computing MAX */
00331                     i__1 = wrkbl, i__2 = *n * 3 + *n * ilaenv_(&c__1, "DORMBR"
00332 , "PRT", n, n, n, &c_n1);
00333                     wrkbl = max(i__1,i__2);
00334 /* Computing MAX */
00335                     i__1 = wrkbl, i__2 = bdspac + *n * 3;
00336                     wrkbl = max(i__1,i__2);
00337                     maxwrk = wrkbl + (*n << 1) * *n;
00338                     minwrk = bdspac + (*n << 1) * *n + *n * 3;
00339                 } else if (wntqs) {
00340 
00341 /*                 Path 3 (M much larger than N, JOBZ='S') */
00342 
00343                     wrkbl = *n + *n * ilaenv_(&c__1, "DGEQRF", " ", m, n, &
00344                             c_n1, &c_n1);
00345 /* Computing MAX */
00346                     i__1 = wrkbl, i__2 = *n + *n * ilaenv_(&c__1, "DORGQR", 
00347                             " ", m, n, n, &c_n1);
00348                     wrkbl = max(i__1,i__2);
00349 /* Computing MAX */
00350                     i__1 = wrkbl, i__2 = *n * 3 + (*n << 1) * ilaenv_(&c__1, 
00351                             "DGEBRD", " ", n, n, &c_n1, &c_n1);
00352                     wrkbl = max(i__1,i__2);
00353 /* Computing MAX */
00354                     i__1 = wrkbl, i__2 = *n * 3 + *n * ilaenv_(&c__1, "DORMBR"
00355 , "QLN", n, n, n, &c_n1);
00356                     wrkbl = max(i__1,i__2);
00357 /* Computing MAX */
00358                     i__1 = wrkbl, i__2 = *n * 3 + *n * ilaenv_(&c__1, "DORMBR"
00359 , "PRT", n, n, n, &c_n1);
00360                     wrkbl = max(i__1,i__2);
00361 /* Computing MAX */
00362                     i__1 = wrkbl, i__2 = bdspac + *n * 3;
00363                     wrkbl = max(i__1,i__2);
00364                     maxwrk = wrkbl + *n * *n;
00365                     minwrk = bdspac + *n * *n + *n * 3;
00366                 } else if (wntqa) {
00367 
00368 /*                 Path 4 (M much larger than N, JOBZ='A') */
00369 
00370                     wrkbl = *n + *n * ilaenv_(&c__1, "DGEQRF", " ", m, n, &
00371                             c_n1, &c_n1);
00372 /* Computing MAX */
00373                     i__1 = wrkbl, i__2 = *n + *m * ilaenv_(&c__1, "DORGQR", 
00374                             " ", m, m, n, &c_n1);
00375                     wrkbl = max(i__1,i__2);
00376 /* Computing MAX */
00377                     i__1 = wrkbl, i__2 = *n * 3 + (*n << 1) * ilaenv_(&c__1, 
00378                             "DGEBRD", " ", n, n, &c_n1, &c_n1);
00379                     wrkbl = max(i__1,i__2);
00380 /* Computing MAX */
00381                     i__1 = wrkbl, i__2 = *n * 3 + *n * ilaenv_(&c__1, "DORMBR"
00382 , "QLN", n, n, n, &c_n1);
00383                     wrkbl = max(i__1,i__2);
00384 /* Computing MAX */
00385                     i__1 = wrkbl, i__2 = *n * 3 + *n * ilaenv_(&c__1, "DORMBR"
00386 , "PRT", n, n, n, &c_n1);
00387                     wrkbl = max(i__1,i__2);
00388 /* Computing MAX */
00389                     i__1 = wrkbl, i__2 = bdspac + *n * 3;
00390                     wrkbl = max(i__1,i__2);
00391                     maxwrk = wrkbl + *n * *n;
00392                     minwrk = bdspac + *n * *n + *n * 3;
00393                 }
00394             } else {
00395 
00396 /*              Path 5 (M at least N, but not much larger) */
00397 
00398                 wrkbl = *n * 3 + (*m + *n) * ilaenv_(&c__1, "DGEBRD", " ", m, 
00399                         n, &c_n1, &c_n1);
00400                 if (wntqn) {
00401 /* Computing MAX */
00402                     i__1 = wrkbl, i__2 = bdspac + *n * 3;
00403                     maxwrk = max(i__1,i__2);
00404                     minwrk = *n * 3 + max(*m,bdspac);
00405                 } else if (wntqo) {
00406 /* Computing MAX */
00407                     i__1 = wrkbl, i__2 = *n * 3 + *n * ilaenv_(&c__1, "DORMBR"
00408 , "QLN", m, n, n, &c_n1);
00409                     wrkbl = max(i__1,i__2);
00410 /* Computing MAX */
00411                     i__1 = wrkbl, i__2 = *n * 3 + *n * ilaenv_(&c__1, "DORMBR"
00412 , "PRT", n, n, n, &c_n1);
00413                     wrkbl = max(i__1,i__2);
00414 /* Computing MAX */
00415                     i__1 = wrkbl, i__2 = bdspac + *n * 3;
00416                     wrkbl = max(i__1,i__2);
00417                     maxwrk = wrkbl + *m * *n;
00418 /* Computing MAX */
00419                     i__1 = *m, i__2 = *n * *n + bdspac;
00420                     minwrk = *n * 3 + max(i__1,i__2);
00421                 } else if (wntqs) {
00422 /* Computing MAX */
00423                     i__1 = wrkbl, i__2 = *n * 3 + *n * ilaenv_(&c__1, "DORMBR"
00424 , "QLN", m, n, n, &c_n1);
00425                     wrkbl = max(i__1,i__2);
00426 /* Computing MAX */
00427                     i__1 = wrkbl, i__2 = *n * 3 + *n * ilaenv_(&c__1, "DORMBR"
00428 , "PRT", n, n, n, &c_n1);
00429                     wrkbl = max(i__1,i__2);
00430 /* Computing MAX */
00431                     i__1 = wrkbl, i__2 = bdspac + *n * 3;
00432                     maxwrk = max(i__1,i__2);
00433                     minwrk = *n * 3 + max(*m,bdspac);
00434                 } else if (wntqa) {
00435 /* Computing MAX */
00436                     i__1 = wrkbl, i__2 = *n * 3 + *m * ilaenv_(&c__1, "DORMBR"
00437 , "QLN", m, m, n, &c_n1);
00438                     wrkbl = max(i__1,i__2);
00439 /* Computing MAX */
00440                     i__1 = wrkbl, i__2 = *n * 3 + *n * ilaenv_(&c__1, "DORMBR"
00441 , "PRT", n, n, n, &c_n1);
00442                     wrkbl = max(i__1,i__2);
00443 /* Computing MAX */
00444                     i__1 = maxwrk, i__2 = bdspac + *n * 3;
00445                     maxwrk = max(i__1,i__2);
00446                     minwrk = *n * 3 + max(*m,bdspac);
00447                 }
00448             }
00449         } else if (minmn > 0) {
00450 
00451 /*           Compute space needed for DBDSDC */
00452 
00453             mnthr = (integer) (minmn * 11. / 6.);
00454             if (wntqn) {
00455                 bdspac = *m * 7;
00456             } else {
00457                 bdspac = *m * 3 * *m + (*m << 2);
00458             }
00459             if (*n >= mnthr) {
00460                 if (wntqn) {
00461 
00462 /*                 Path 1t (N much larger than M, JOBZ='N') */
00463 
00464                     wrkbl = *m + *m * ilaenv_(&c__1, "DGELQF", " ", m, n, &
00465                             c_n1, &c_n1);
00466 /* Computing MAX */
00467                     i__1 = wrkbl, i__2 = *m * 3 + (*m << 1) * ilaenv_(&c__1, 
00468                             "DGEBRD", " ", m, m, &c_n1, &c_n1);
00469                     wrkbl = max(i__1,i__2);
00470 /* Computing MAX */
00471                     i__1 = wrkbl, i__2 = bdspac + *m;
00472                     maxwrk = max(i__1,i__2);
00473                     minwrk = bdspac + *m;
00474                 } else if (wntqo) {
00475 
00476 /*                 Path 2t (N much larger than M, JOBZ='O') */
00477 
00478                     wrkbl = *m + *m * ilaenv_(&c__1, "DGELQF", " ", m, n, &
00479                             c_n1, &c_n1);
00480 /* Computing MAX */
00481                     i__1 = wrkbl, i__2 = *m + *m * ilaenv_(&c__1, "DORGLQ", 
00482                             " ", m, n, m, &c_n1);
00483                     wrkbl = max(i__1,i__2);
00484 /* Computing MAX */
00485                     i__1 = wrkbl, i__2 = *m * 3 + (*m << 1) * ilaenv_(&c__1, 
00486                             "DGEBRD", " ", m, m, &c_n1, &c_n1);
00487                     wrkbl = max(i__1,i__2);
00488 /* Computing MAX */
00489                     i__1 = wrkbl, i__2 = *m * 3 + *m * ilaenv_(&c__1, "DORMBR"
00490 , "QLN", m, m, m, &c_n1);
00491                     wrkbl = max(i__1,i__2);
00492 /* Computing MAX */
00493                     i__1 = wrkbl, i__2 = *m * 3 + *m * ilaenv_(&c__1, "DORMBR"
00494 , "PRT", m, m, m, &c_n1);
00495                     wrkbl = max(i__1,i__2);
00496 /* Computing MAX */
00497                     i__1 = wrkbl, i__2 = bdspac + *m * 3;
00498                     wrkbl = max(i__1,i__2);
00499                     maxwrk = wrkbl + (*m << 1) * *m;
00500                     minwrk = bdspac + (*m << 1) * *m + *m * 3;
00501                 } else if (wntqs) {
00502 
00503 /*                 Path 3t (N much larger than M, JOBZ='S') */
00504 
00505                     wrkbl = *m + *m * ilaenv_(&c__1, "DGELQF", " ", m, n, &
00506                             c_n1, &c_n1);
00507 /* Computing MAX */
00508                     i__1 = wrkbl, i__2 = *m + *m * ilaenv_(&c__1, "DORGLQ", 
00509                             " ", m, n, m, &c_n1);
00510                     wrkbl = max(i__1,i__2);
00511 /* Computing MAX */
00512                     i__1 = wrkbl, i__2 = *m * 3 + (*m << 1) * ilaenv_(&c__1, 
00513                             "DGEBRD", " ", m, m, &c_n1, &c_n1);
00514                     wrkbl = max(i__1,i__2);
00515 /* Computing MAX */
00516                     i__1 = wrkbl, i__2 = *m * 3 + *m * ilaenv_(&c__1, "DORMBR"
00517 , "QLN", m, m, m, &c_n1);
00518                     wrkbl = max(i__1,i__2);
00519 /* Computing MAX */
00520                     i__1 = wrkbl, i__2 = *m * 3 + *m * ilaenv_(&c__1, "DORMBR"
00521 , "PRT", m, m, m, &c_n1);
00522                     wrkbl = max(i__1,i__2);
00523 /* Computing MAX */
00524                     i__1 = wrkbl, i__2 = bdspac + *m * 3;
00525                     wrkbl = max(i__1,i__2);
00526                     maxwrk = wrkbl + *m * *m;
00527                     minwrk = bdspac + *m * *m + *m * 3;
00528                 } else if (wntqa) {
00529 
00530 /*                 Path 4t (N much larger than M, JOBZ='A') */
00531 
00532                     wrkbl = *m + *m * ilaenv_(&c__1, "DGELQF", " ", m, n, &
00533                             c_n1, &c_n1);
00534 /* Computing MAX */
00535                     i__1 = wrkbl, i__2 = *m + *n * ilaenv_(&c__1, "DORGLQ", 
00536                             " ", n, n, m, &c_n1);
00537                     wrkbl = max(i__1,i__2);
00538 /* Computing MAX */
00539                     i__1 = wrkbl, i__2 = *m * 3 + (*m << 1) * ilaenv_(&c__1, 
00540                             "DGEBRD", " ", m, m, &c_n1, &c_n1);
00541                     wrkbl = max(i__1,i__2);
00542 /* Computing MAX */
00543                     i__1 = wrkbl, i__2 = *m * 3 + *m * ilaenv_(&c__1, "DORMBR"
00544 , "QLN", m, m, m, &c_n1);
00545                     wrkbl = max(i__1,i__2);
00546 /* Computing MAX */
00547                     i__1 = wrkbl, i__2 = *m * 3 + *m * ilaenv_(&c__1, "DORMBR"
00548 , "PRT", m, m, m, &c_n1);
00549                     wrkbl = max(i__1,i__2);
00550 /* Computing MAX */
00551                     i__1 = wrkbl, i__2 = bdspac + *m * 3;
00552                     wrkbl = max(i__1,i__2);
00553                     maxwrk = wrkbl + *m * *m;
00554                     minwrk = bdspac + *m * *m + *m * 3;
00555                 }
00556             } else {
00557 
00558 /*              Path 5t (N greater than M, but not much larger) */
00559 
00560                 wrkbl = *m * 3 + (*m + *n) * ilaenv_(&c__1, "DGEBRD", " ", m, 
00561                         n, &c_n1, &c_n1);
00562                 if (wntqn) {
00563 /* Computing MAX */
00564                     i__1 = wrkbl, i__2 = bdspac + *m * 3;
00565                     maxwrk = max(i__1,i__2);
00566                     minwrk = *m * 3 + max(*n,bdspac);
00567                 } else if (wntqo) {
00568 /* Computing MAX */
00569                     i__1 = wrkbl, i__2 = *m * 3 + *m * ilaenv_(&c__1, "DORMBR"
00570 , "QLN", m, m, n, &c_n1);
00571                     wrkbl = max(i__1,i__2);
00572 /* Computing MAX */
00573                     i__1 = wrkbl, i__2 = *m * 3 + *m * ilaenv_(&c__1, "DORMBR"
00574 , "PRT", m, n, m, &c_n1);
00575                     wrkbl = max(i__1,i__2);
00576 /* Computing MAX */
00577                     i__1 = wrkbl, i__2 = bdspac + *m * 3;
00578                     wrkbl = max(i__1,i__2);
00579                     maxwrk = wrkbl + *m * *n;
00580 /* Computing MAX */
00581                     i__1 = *n, i__2 = *m * *m + bdspac;
00582                     minwrk = *m * 3 + max(i__1,i__2);
00583                 } else if (wntqs) {
00584 /* Computing MAX */
00585                     i__1 = wrkbl, i__2 = *m * 3 + *m * ilaenv_(&c__1, "DORMBR"
00586 , "QLN", m, m, n, &c_n1);
00587                     wrkbl = max(i__1,i__2);
00588 /* Computing MAX */
00589                     i__1 = wrkbl, i__2 = *m * 3 + *m * ilaenv_(&c__1, "DORMBR"
00590 , "PRT", m, n, m, &c_n1);
00591                     wrkbl = max(i__1,i__2);
00592 /* Computing MAX */
00593                     i__1 = wrkbl, i__2 = bdspac + *m * 3;
00594                     maxwrk = max(i__1,i__2);
00595                     minwrk = *m * 3 + max(*n,bdspac);
00596                 } else if (wntqa) {
00597 /* Computing MAX */
00598                     i__1 = wrkbl, i__2 = *m * 3 + *m * ilaenv_(&c__1, "DORMBR"
00599 , "QLN", m, m, n, &c_n1);
00600                     wrkbl = max(i__1,i__2);
00601 /* Computing MAX */
00602                     i__1 = wrkbl, i__2 = *m * 3 + *m * ilaenv_(&c__1, "DORMBR"
00603 , "PRT", n, n, m, &c_n1);
00604                     wrkbl = max(i__1,i__2);
00605 /* Computing MAX */
00606                     i__1 = wrkbl, i__2 = bdspac + *m * 3;
00607                     maxwrk = max(i__1,i__2);
00608                     minwrk = *m * 3 + max(*n,bdspac);
00609                 }
00610             }
00611         }
00612         maxwrk = max(maxwrk,minwrk);
00613         work[1] = (doublereal) maxwrk;
00614 
00615         if (*lwork < minwrk && ! lquery) {
00616             *info = -12;
00617         }
00618     }
00619 
00620     if (*info != 0) {
00621         i__1 = -(*info);
00622         xerbla_("DGESDD", &i__1);
00623         return 0;
00624     } else if (lquery) {
00625         return 0;
00626     }
00627 
00628 /*     Quick return if possible */
00629 
00630     if (*m == 0 || *n == 0) {
00631         return 0;
00632     }
00633 
00634 /*     Get machine constants */
00635 
00636     eps = dlamch_("P");
00637     smlnum = sqrt(dlamch_("S")) / eps;
00638     bignum = 1. / smlnum;
00639 
00640 /*     Scale A if max element outside range [SMLNUM,BIGNUM] */
00641 
00642     anrm = dlange_("M", m, n, &a[a_offset], lda, dum);
00643     iscl = 0;
00644     if (anrm > 0. && anrm < smlnum) {
00645         iscl = 1;
00646         dlascl_("G", &c__0, &c__0, &anrm, &smlnum, m, n, &a[a_offset], lda, &
00647                 ierr);
00648     } else if (anrm > bignum) {
00649         iscl = 1;
00650         dlascl_("G", &c__0, &c__0, &anrm, &bignum, m, n, &a[a_offset], lda, &
00651                 ierr);
00652     }
00653 
00654     if (*m >= *n) {
00655 
00656 /*        A has at least as many rows as columns. If A has sufficiently */
00657 /*        more rows than columns, first reduce using the QR */
00658 /*        decomposition (if sufficient workspace available) */
00659 
00660         if (*m >= mnthr) {
00661 
00662             if (wntqn) {
00663 
00664 /*              Path 1 (M much larger than N, JOBZ='N') */
00665 /*              No singular vectors to be computed */
00666 
00667                 itau = 1;
00668                 nwork = itau + *n;
00669 
00670 /*              Compute A=Q*R */
00671 /*              (Workspace: need 2*N, prefer N+N*NB) */
00672 
00673                 i__1 = *lwork - nwork + 1;
00674                 dgeqrf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
00675                         i__1, &ierr);
00676 
00677 /*              Zero out below R */
00678 
00679                 i__1 = *n - 1;
00680                 i__2 = *n - 1;
00681                 dlaset_("L", &i__1, &i__2, &c_b227, &c_b227, &a[a_dim1 + 2], 
00682                         lda);
00683                 ie = 1;
00684                 itauq = ie + *n;
00685                 itaup = itauq + *n;
00686                 nwork = itaup + *n;
00687 
00688 /*              Bidiagonalize R in A */
00689 /*              (Workspace: need 4*N, prefer 3*N+2*N*NB) */
00690 
00691                 i__1 = *lwork - nwork + 1;
00692                 dgebrd_(n, n, &a[a_offset], lda, &s[1], &work[ie], &work[
00693                         itauq], &work[itaup], &work[nwork], &i__1, &ierr);
00694                 nwork = ie + *n;
00695 
00696 /*              Perform bidiagonal SVD, computing singular values only */
00697 /*              (Workspace: need N+BDSPAC) */
00698 
00699                 dbdsdc_("U", "N", n, &s[1], &work[ie], dum, &c__1, dum, &c__1, 
00700                          dum, idum, &work[nwork], &iwork[1], info);
00701 
00702             } else if (wntqo) {
00703 
00704 /*              Path 2 (M much larger than N, JOBZ = 'O') */
00705 /*              N left singular vectors to be overwritten on A and */
00706 /*              N right singular vectors to be computed in VT */
00707 
00708                 ir = 1;
00709 
00710 /*              WORK(IR) is LDWRKR by N */
00711 
00712                 if (*lwork >= *lda * *n + *n * *n + *n * 3 + bdspac) {
00713                     ldwrkr = *lda;
00714                 } else {
00715                     ldwrkr = (*lwork - *n * *n - *n * 3 - bdspac) / *n;
00716                 }
00717                 itau = ir + ldwrkr * *n;
00718                 nwork = itau + *n;
00719 
00720 /*              Compute A=Q*R */
00721 /*              (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */
00722 
00723                 i__1 = *lwork - nwork + 1;
00724                 dgeqrf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
00725                         i__1, &ierr);
00726 
00727 /*              Copy R to WORK(IR), zeroing out below it */
00728 
00729                 dlacpy_("U", n, n, &a[a_offset], lda, &work[ir], &ldwrkr);
00730                 i__1 = *n - 1;
00731                 i__2 = *n - 1;
00732                 dlaset_("L", &i__1, &i__2, &c_b227, &c_b227, &work[ir + 1], &
00733                         ldwrkr);
00734 
00735 /*              Generate Q in A */
00736 /*              (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */
00737 
00738                 i__1 = *lwork - nwork + 1;
00739                 dorgqr_(m, n, n, &a[a_offset], lda, &work[itau], &work[nwork], 
00740                          &i__1, &ierr);
00741                 ie = itau;
00742                 itauq = ie + *n;
00743                 itaup = itauq + *n;
00744                 nwork = itaup + *n;
00745 
00746 /*              Bidiagonalize R in VT, copying result to WORK(IR) */
00747 /*              (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB) */
00748 
00749                 i__1 = *lwork - nwork + 1;
00750                 dgebrd_(n, n, &work[ir], &ldwrkr, &s[1], &work[ie], &work[
00751                         itauq], &work[itaup], &work[nwork], &i__1, &ierr);
00752 
00753 /*              WORK(IU) is N by N */
00754 
00755                 iu = nwork;
00756                 nwork = iu + *n * *n;
00757 
00758 /*              Perform bidiagonal SVD, computing left singular vectors */
00759 /*              of bidiagonal matrix in WORK(IU) and computing right */
00760 /*              singular vectors of bidiagonal matrix in VT */
00761 /*              (Workspace: need N+N*N+BDSPAC) */
00762 
00763                 dbdsdc_("U", "I", n, &s[1], &work[ie], &work[iu], n, &vt[
00764                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
00765                         info);
00766 
00767 /*              Overwrite WORK(IU) by left singular vectors of R */
00768 /*              and VT by right singular vectors of R */
00769 /*              (Workspace: need 2*N*N+3*N, prefer 2*N*N+2*N+N*NB) */
00770 
00771                 i__1 = *lwork - nwork + 1;
00772                 dormbr_("Q", "L", "N", n, n, n, &work[ir], &ldwrkr, &work[
00773                         itauq], &work[iu], n, &work[nwork], &i__1, &ierr);
00774                 i__1 = *lwork - nwork + 1;
00775                 dormbr_("P", "R", "T", n, n, n, &work[ir], &ldwrkr, &work[
00776                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__1, &
00777                         ierr);
00778 
00779 /*              Multiply Q in A by left singular vectors of R in */
00780 /*              WORK(IU), storing result in WORK(IR) and copying to A */
00781 /*              (Workspace: need 2*N*N, prefer N*N+M*N) */
00782 
00783                 i__1 = *m;
00784                 i__2 = ldwrkr;
00785                 for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += 
00786                         i__2) {
00787 /* Computing MIN */
00788                     i__3 = *m - i__ + 1;
00789                     chunk = min(i__3,ldwrkr);
00790                     dgemm_("N", "N", &chunk, n, n, &c_b248, &a[i__ + a_dim1], 
00791                             lda, &work[iu], n, &c_b227, &work[ir], &ldwrkr);
00792                     dlacpy_("F", &chunk, n, &work[ir], &ldwrkr, &a[i__ + 
00793                             a_dim1], lda);
00794 /* L10: */
00795                 }
00796 
00797             } else if (wntqs) {
00798 
00799 /*              Path 3 (M much larger than N, JOBZ='S') */
00800 /*              N left singular vectors to be computed in U and */
00801 /*              N right singular vectors to be computed in VT */
00802 
00803                 ir = 1;
00804 
00805 /*              WORK(IR) is N by N */
00806 
00807                 ldwrkr = *n;
00808                 itau = ir + ldwrkr * *n;
00809                 nwork = itau + *n;
00810 
00811 /*              Compute A=Q*R */
00812 /*              (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */
00813 
00814                 i__2 = *lwork - nwork + 1;
00815                 dgeqrf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
00816                         i__2, &ierr);
00817 
00818 /*              Copy R to WORK(IR), zeroing out below it */
00819 
00820                 dlacpy_("U", n, n, &a[a_offset], lda, &work[ir], &ldwrkr);
00821                 i__2 = *n - 1;
00822                 i__1 = *n - 1;
00823                 dlaset_("L", &i__2, &i__1, &c_b227, &c_b227, &work[ir + 1], &
00824                         ldwrkr);
00825 
00826 /*              Generate Q in A */
00827 /*              (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */
00828 
00829                 i__2 = *lwork - nwork + 1;
00830                 dorgqr_(m, n, n, &a[a_offset], lda, &work[itau], &work[nwork], 
00831                          &i__2, &ierr);
00832                 ie = itau;
00833                 itauq = ie + *n;
00834                 itaup = itauq + *n;
00835                 nwork = itaup + *n;
00836 
00837 /*              Bidiagonalize R in WORK(IR) */
00838 /*              (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB) */
00839 
00840                 i__2 = *lwork - nwork + 1;
00841                 dgebrd_(n, n, &work[ir], &ldwrkr, &s[1], &work[ie], &work[
00842                         itauq], &work[itaup], &work[nwork], &i__2, &ierr);
00843 
00844 /*              Perform bidiagonal SVD, computing left singular vectors */
00845 /*              of bidiagoal matrix in U and computing right singular */
00846 /*              vectors of bidiagonal matrix in VT */
00847 /*              (Workspace: need N+BDSPAC) */
00848 
00849                 dbdsdc_("U", "I", n, &s[1], &work[ie], &u[u_offset], ldu, &vt[
00850                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
00851                         info);
00852 
00853 /*              Overwrite U by left singular vectors of R and VT */
00854 /*              by right singular vectors of R */
00855 /*              (Workspace: need N*N+3*N, prefer N*N+2*N+N*NB) */
00856 
00857                 i__2 = *lwork - nwork + 1;
00858                 dormbr_("Q", "L", "N", n, n, n, &work[ir], &ldwrkr, &work[
00859                         itauq], &u[u_offset], ldu, &work[nwork], &i__2, &ierr);
00860 
00861                 i__2 = *lwork - nwork + 1;
00862                 dormbr_("P", "R", "T", n, n, n, &work[ir], &ldwrkr, &work[
00863                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__2, &
00864                         ierr);
00865 
00866 /*              Multiply Q in A by left singular vectors of R in */
00867 /*              WORK(IR), storing result in U */
00868 /*              (Workspace: need N*N) */
00869 
00870                 dlacpy_("F", n, n, &u[u_offset], ldu, &work[ir], &ldwrkr);
00871                 dgemm_("N", "N", m, n, n, &c_b248, &a[a_offset], lda, &work[
00872                         ir], &ldwrkr, &c_b227, &u[u_offset], ldu);
00873 
00874             } else if (wntqa) {
00875 
00876 /*              Path 4 (M much larger than N, JOBZ='A') */
00877 /*              M left singular vectors to be computed in U and */
00878 /*              N right singular vectors to be computed in VT */
00879 
00880                 iu = 1;
00881 
00882 /*              WORK(IU) is N by N */
00883 
00884                 ldwrku = *n;
00885                 itau = iu + ldwrku * *n;
00886                 nwork = itau + *n;
00887 
00888 /*              Compute A=Q*R, copying result to U */
00889 /*              (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */
00890 
00891                 i__2 = *lwork - nwork + 1;
00892                 dgeqrf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
00893                         i__2, &ierr);
00894                 dlacpy_("L", m, n, &a[a_offset], lda, &u[u_offset], ldu);
00895 
00896 /*              Generate Q in U */
00897 /*              (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */
00898                 i__2 = *lwork - nwork + 1;
00899                 dorgqr_(m, m, n, &u[u_offset], ldu, &work[itau], &work[nwork], 
00900                          &i__2, &ierr);
00901 
00902 /*              Produce R in A, zeroing out other entries */
00903 
00904                 i__2 = *n - 1;
00905                 i__1 = *n - 1;
00906                 dlaset_("L", &i__2, &i__1, &c_b227, &c_b227, &a[a_dim1 + 2], 
00907                         lda);
00908                 ie = itau;
00909                 itauq = ie + *n;
00910                 itaup = itauq + *n;
00911                 nwork = itaup + *n;
00912 
00913 /*              Bidiagonalize R in A */
00914 /*              (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB) */
00915 
00916                 i__2 = *lwork - nwork + 1;
00917                 dgebrd_(n, n, &a[a_offset], lda, &s[1], &work[ie], &work[
00918                         itauq], &work[itaup], &work[nwork], &i__2, &ierr);
00919 
00920 /*              Perform bidiagonal SVD, computing left singular vectors */
00921 /*              of bidiagonal matrix in WORK(IU) and computing right */
00922 /*              singular vectors of bidiagonal matrix in VT */
00923 /*              (Workspace: need N+N*N+BDSPAC) */
00924 
00925                 dbdsdc_("U", "I", n, &s[1], &work[ie], &work[iu], n, &vt[
00926                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
00927                         info);
00928 
00929 /*              Overwrite WORK(IU) by left singular vectors of R and VT */
00930 /*              by right singular vectors of R */
00931 /*              (Workspace: need N*N+3*N, prefer N*N+2*N+N*NB) */
00932 
00933                 i__2 = *lwork - nwork + 1;
00934                 dormbr_("Q", "L", "N", n, n, n, &a[a_offset], lda, &work[
00935                         itauq], &work[iu], &ldwrku, &work[nwork], &i__2, &
00936                         ierr);
00937                 i__2 = *lwork - nwork + 1;
00938                 dormbr_("P", "R", "T", n, n, n, &a[a_offset], lda, &work[
00939                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__2, &
00940                         ierr);
00941 
00942 /*              Multiply Q in U by left singular vectors of R in */
00943 /*              WORK(IU), storing result in A */
00944 /*              (Workspace: need N*N) */
00945 
00946                 dgemm_("N", "N", m, n, n, &c_b248, &u[u_offset], ldu, &work[
00947                         iu], &ldwrku, &c_b227, &a[a_offset], lda);
00948 
00949 /*              Copy left singular vectors of A from A to U */
00950 
00951                 dlacpy_("F", m, n, &a[a_offset], lda, &u[u_offset], ldu);
00952 
00953             }
00954 
00955         } else {
00956 
00957 /*           M .LT. MNTHR */
00958 
00959 /*           Path 5 (M at least N, but not much larger) */
00960 /*           Reduce to bidiagonal form without QR decomposition */
00961 
00962             ie = 1;
00963             itauq = ie + *n;
00964             itaup = itauq + *n;
00965             nwork = itaup + *n;
00966 
00967 /*           Bidiagonalize A */
00968 /*           (Workspace: need 3*N+M, prefer 3*N+(M+N)*NB) */
00969 
00970             i__2 = *lwork - nwork + 1;
00971             dgebrd_(m, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &
00972                     work[itaup], &work[nwork], &i__2, &ierr);
00973             if (wntqn) {
00974 
00975 /*              Perform bidiagonal SVD, only computing singular values */
00976 /*              (Workspace: need N+BDSPAC) */
00977 
00978                 dbdsdc_("U", "N", n, &s[1], &work[ie], dum, &c__1, dum, &c__1, 
00979                          dum, idum, &work[nwork], &iwork[1], info);
00980             } else if (wntqo) {
00981                 iu = nwork;
00982                 if (*lwork >= *m * *n + *n * 3 + bdspac) {
00983 
00984 /*                 WORK( IU ) is M by N */
00985 
00986                     ldwrku = *m;
00987                     nwork = iu + ldwrku * *n;
00988                     dlaset_("F", m, n, &c_b227, &c_b227, &work[iu], &ldwrku);
00989                 } else {
00990 
00991 /*                 WORK( IU ) is N by N */
00992 
00993                     ldwrku = *n;
00994                     nwork = iu + ldwrku * *n;
00995 
00996 /*                 WORK(IR) is LDWRKR by N */
00997 
00998                     ir = nwork;
00999                     ldwrkr = (*lwork - *n * *n - *n * 3) / *n;
01000                 }
01001                 nwork = iu + ldwrku * *n;
01002 
01003 /*              Perform bidiagonal SVD, computing left singular vectors */
01004 /*              of bidiagonal matrix in WORK(IU) and computing right */
01005 /*              singular vectors of bidiagonal matrix in VT */
01006 /*              (Workspace: need N+N*N+BDSPAC) */
01007 
01008                 dbdsdc_("U", "I", n, &s[1], &work[ie], &work[iu], &ldwrku, &
01009                         vt[vt_offset], ldvt, dum, idum, &work[nwork], &iwork[
01010                         1], info);
01011 
01012 /*              Overwrite VT by right singular vectors of A */
01013 /*              (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */
01014 
01015                 i__2 = *lwork - nwork + 1;
01016                 dormbr_("P", "R", "T", n, n, n, &a[a_offset], lda, &work[
01017                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__2, &
01018                         ierr);
01019 
01020                 if (*lwork >= *m * *n + *n * 3 + bdspac) {
01021 
01022 /*                 Overwrite WORK(IU) by left singular vectors of A */
01023 /*                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */
01024 
01025                     i__2 = *lwork - nwork + 1;
01026                     dormbr_("Q", "L", "N", m, n, n, &a[a_offset], lda, &work[
01027                             itauq], &work[iu], &ldwrku, &work[nwork], &i__2, &
01028                             ierr);
01029 
01030 /*                 Copy left singular vectors of A from WORK(IU) to A */
01031 
01032                     dlacpy_("F", m, n, &work[iu], &ldwrku, &a[a_offset], lda);
01033                 } else {
01034 
01035 /*                 Generate Q in A */
01036 /*                 (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */
01037 
01038                     i__2 = *lwork - nwork + 1;
01039                     dorgbr_("Q", m, n, n, &a[a_offset], lda, &work[itauq], &
01040                             work[nwork], &i__2, &ierr);
01041 
01042 /*                 Multiply Q in A by left singular vectors of */
01043 /*                 bidiagonal matrix in WORK(IU), storing result in */
01044 /*                 WORK(IR) and copying to A */
01045 /*                 (Workspace: need 2*N*N, prefer N*N+M*N) */
01046 
01047                     i__2 = *m;
01048                     i__1 = ldwrkr;
01049                     for (i__ = 1; i__1 < 0 ? i__ >= i__2 : i__ <= i__2; i__ +=
01050                              i__1) {
01051 /* Computing MIN */
01052                         i__3 = *m - i__ + 1;
01053                         chunk = min(i__3,ldwrkr);
01054                         dgemm_("N", "N", &chunk, n, n, &c_b248, &a[i__ + 
01055                                 a_dim1], lda, &work[iu], &ldwrku, &c_b227, &
01056                                 work[ir], &ldwrkr);
01057                         dlacpy_("F", &chunk, n, &work[ir], &ldwrkr, &a[i__ + 
01058                                 a_dim1], lda);
01059 /* L20: */
01060                     }
01061                 }
01062 
01063             } else if (wntqs) {
01064 
01065 /*              Perform bidiagonal SVD, computing left singular vectors */
01066 /*              of bidiagonal matrix in U and computing right singular */
01067 /*              vectors of bidiagonal matrix in VT */
01068 /*              (Workspace: need N+BDSPAC) */
01069 
01070                 dlaset_("F", m, n, &c_b227, &c_b227, &u[u_offset], ldu);
01071                 dbdsdc_("U", "I", n, &s[1], &work[ie], &u[u_offset], ldu, &vt[
01072                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
01073                         info);
01074 
01075 /*              Overwrite U by left singular vectors of A and VT */
01076 /*              by right singular vectors of A */
01077 /*              (Workspace: need 3*N, prefer 2*N+N*NB) */
01078 
01079                 i__1 = *lwork - nwork + 1;
01080                 dormbr_("Q", "L", "N", m, n, n, &a[a_offset], lda, &work[
01081                         itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
01082                 i__1 = *lwork - nwork + 1;
01083                 dormbr_("P", "R", "T", n, n, n, &a[a_offset], lda, &work[
01084                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__1, &
01085                         ierr);
01086             } else if (wntqa) {
01087 
01088 /*              Perform bidiagonal SVD, computing left singular vectors */
01089 /*              of bidiagonal matrix in U and computing right singular */
01090 /*              vectors of bidiagonal matrix in VT */
01091 /*              (Workspace: need N+BDSPAC) */
01092 
01093                 dlaset_("F", m, m, &c_b227, &c_b227, &u[u_offset], ldu);
01094                 dbdsdc_("U", "I", n, &s[1], &work[ie], &u[u_offset], ldu, &vt[
01095                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
01096                         info);
01097 
01098 /*              Set the right corner of U to identity matrix */
01099 
01100                 if (*m > *n) {
01101                     i__1 = *m - *n;
01102                     i__2 = *m - *n;
01103                     dlaset_("F", &i__1, &i__2, &c_b227, &c_b248, &u[*n + 1 + (
01104                             *n + 1) * u_dim1], ldu);
01105                 }
01106 
01107 /*              Overwrite U by left singular vectors of A and VT */
01108 /*              by right singular vectors of A */
01109 /*              (Workspace: need N*N+2*N+M, prefer N*N+2*N+M*NB) */
01110 
01111                 i__1 = *lwork - nwork + 1;
01112                 dormbr_("Q", "L", "N", m, m, n, &a[a_offset], lda, &work[
01113                         itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
01114                 i__1 = *lwork - nwork + 1;
01115                 dormbr_("P", "R", "T", n, n, m, &a[a_offset], lda, &work[
01116                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__1, &
01117                         ierr);
01118             }
01119 
01120         }
01121 
01122     } else {
01123 
01124 /*        A has more columns than rows. If A has sufficiently more */
01125 /*        columns than rows, first reduce using the LQ decomposition (if */
01126 /*        sufficient workspace available) */
01127 
01128         if (*n >= mnthr) {
01129 
01130             if (wntqn) {
01131 
01132 /*              Path 1t (N much larger than M, JOBZ='N') */
01133 /*              No singular vectors to be computed */
01134 
01135                 itau = 1;
01136                 nwork = itau + *m;
01137 
01138 /*              Compute A=L*Q */
01139 /*              (Workspace: need 2*M, prefer M+M*NB) */
01140 
01141                 i__1 = *lwork - nwork + 1;
01142                 dgelqf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
01143                         i__1, &ierr);
01144 
01145 /*              Zero out above L */
01146 
01147                 i__1 = *m - 1;
01148                 i__2 = *m - 1;
01149                 dlaset_("U", &i__1, &i__2, &c_b227, &c_b227, &a[(a_dim1 << 1) 
01150                         + 1], lda);
01151                 ie = 1;
01152                 itauq = ie + *m;
01153                 itaup = itauq + *m;
01154                 nwork = itaup + *m;
01155 
01156 /*              Bidiagonalize L in A */
01157 /*              (Workspace: need 4*M, prefer 3*M+2*M*NB) */
01158 
01159                 i__1 = *lwork - nwork + 1;
01160                 dgebrd_(m, m, &a[a_offset], lda, &s[1], &work[ie], &work[
01161                         itauq], &work[itaup], &work[nwork], &i__1, &ierr);
01162                 nwork = ie + *m;
01163 
01164 /*              Perform bidiagonal SVD, computing singular values only */
01165 /*              (Workspace: need M+BDSPAC) */
01166 
01167                 dbdsdc_("U", "N", m, &s[1], &work[ie], dum, &c__1, dum, &c__1, 
01168                          dum, idum, &work[nwork], &iwork[1], info);
01169 
01170             } else if (wntqo) {
01171 
01172 /*              Path 2t (N much larger than M, JOBZ='O') */
01173 /*              M right singular vectors to be overwritten on A and */
01174 /*              M left singular vectors to be computed in U */
01175 
01176                 ivt = 1;
01177 
01178 /*              IVT is M by M */
01179 
01180                 il = ivt + *m * *m;
01181                 if (*lwork >= *m * *n + *m * *m + *m * 3 + bdspac) {
01182 
01183 /*                 WORK(IL) is M by N */
01184 
01185                     ldwrkl = *m;
01186                     chunk = *n;
01187                 } else {
01188                     ldwrkl = *m;
01189                     chunk = (*lwork - *m * *m) / *m;
01190                 }
01191                 itau = il + ldwrkl * *m;
01192                 nwork = itau + *m;
01193 
01194 /*              Compute A=L*Q */
01195 /*              (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */
01196 
01197                 i__1 = *lwork - nwork + 1;
01198                 dgelqf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
01199                         i__1, &ierr);
01200 
01201 /*              Copy L to WORK(IL), zeroing about above it */
01202 
01203                 dlacpy_("L", m, m, &a[a_offset], lda, &work[il], &ldwrkl);
01204                 i__1 = *m - 1;
01205                 i__2 = *m - 1;
01206                 dlaset_("U", &i__1, &i__2, &c_b227, &c_b227, &work[il + 
01207                         ldwrkl], &ldwrkl);
01208 
01209 /*              Generate Q in A */
01210 /*              (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */
01211 
01212                 i__1 = *lwork - nwork + 1;
01213                 dorglq_(m, n, m, &a[a_offset], lda, &work[itau], &work[nwork], 
01214                          &i__1, &ierr);
01215                 ie = itau;
01216                 itauq = ie + *m;
01217                 itaup = itauq + *m;
01218                 nwork = itaup + *m;
01219 
01220 /*              Bidiagonalize L in WORK(IL) */
01221 /*              (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB) */
01222 
01223                 i__1 = *lwork - nwork + 1;
01224                 dgebrd_(m, m, &work[il], &ldwrkl, &s[1], &work[ie], &work[
01225                         itauq], &work[itaup], &work[nwork], &i__1, &ierr);
01226 
01227 /*              Perform bidiagonal SVD, computing left singular vectors */
01228 /*              of bidiagonal matrix in U, and computing right singular */
01229 /*              vectors of bidiagonal matrix in WORK(IVT) */
01230 /*              (Workspace: need M+M*M+BDSPAC) */
01231 
01232                 dbdsdc_("U", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &
01233                         work[ivt], m, dum, idum, &work[nwork], &iwork[1], 
01234                         info);
01235 
01236 /*              Overwrite U by left singular vectors of L and WORK(IVT) */
01237 /*              by right singular vectors of L */
01238 /*              (Workspace: need 2*M*M+3*M, prefer 2*M*M+2*M+M*NB) */
01239 
01240                 i__1 = *lwork - nwork + 1;
01241                 dormbr_("Q", "L", "N", m, m, m, &work[il], &ldwrkl, &work[
01242                         itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
01243                 i__1 = *lwork - nwork + 1;
01244                 dormbr_("P", "R", "T", m, m, m, &work[il], &ldwrkl, &work[
01245                         itaup], &work[ivt], m, &work[nwork], &i__1, &ierr);
01246 
01247 /*              Multiply right singular vectors of L in WORK(IVT) by Q */
01248 /*              in A, storing result in WORK(IL) and copying to A */
01249 /*              (Workspace: need 2*M*M, prefer M*M+M*N) */
01250 
01251                 i__1 = *n;
01252                 i__2 = chunk;
01253                 for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += 
01254                         i__2) {
01255 /* Computing MIN */
01256                     i__3 = *n - i__ + 1;
01257                     blk = min(i__3,chunk);
01258                     dgemm_("N", "N", m, &blk, m, &c_b248, &work[ivt], m, &a[
01259                             i__ * a_dim1 + 1], lda, &c_b227, &work[il], &
01260                             ldwrkl);
01261                     dlacpy_("F", m, &blk, &work[il], &ldwrkl, &a[i__ * a_dim1 
01262                             + 1], lda);
01263 /* L30: */
01264                 }
01265 
01266             } else if (wntqs) {
01267 
01268 /*              Path 3t (N much larger than M, JOBZ='S') */
01269 /*              M right singular vectors to be computed in VT and */
01270 /*              M left singular vectors to be computed in U */
01271 
01272                 il = 1;
01273 
01274 /*              WORK(IL) is M by M */
01275 
01276                 ldwrkl = *m;
01277                 itau = il + ldwrkl * *m;
01278                 nwork = itau + *m;
01279 
01280 /*              Compute A=L*Q */
01281 /*              (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */
01282 
01283                 i__2 = *lwork - nwork + 1;
01284                 dgelqf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
01285                         i__2, &ierr);
01286 
01287 /*              Copy L to WORK(IL), zeroing out above it */
01288 
01289                 dlacpy_("L", m, m, &a[a_offset], lda, &work[il], &ldwrkl);
01290                 i__2 = *m - 1;
01291                 i__1 = *m - 1;
01292                 dlaset_("U", &i__2, &i__1, &c_b227, &c_b227, &work[il + 
01293                         ldwrkl], &ldwrkl);
01294 
01295 /*              Generate Q in A */
01296 /*              (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */
01297 
01298                 i__2 = *lwork - nwork + 1;
01299                 dorglq_(m, n, m, &a[a_offset], lda, &work[itau], &work[nwork], 
01300                          &i__2, &ierr);
01301                 ie = itau;
01302                 itauq = ie + *m;
01303                 itaup = itauq + *m;
01304                 nwork = itaup + *m;
01305 
01306 /*              Bidiagonalize L in WORK(IU), copying result to U */
01307 /*              (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB) */
01308 
01309                 i__2 = *lwork - nwork + 1;
01310                 dgebrd_(m, m, &work[il], &ldwrkl, &s[1], &work[ie], &work[
01311                         itauq], &work[itaup], &work[nwork], &i__2, &ierr);
01312 
01313 /*              Perform bidiagonal SVD, computing left singular vectors */
01314 /*              of bidiagonal matrix in U and computing right singular */
01315 /*              vectors of bidiagonal matrix in VT */
01316 /*              (Workspace: need M+BDSPAC) */
01317 
01318                 dbdsdc_("U", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &vt[
01319                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
01320                         info);
01321 
01322 /*              Overwrite U by left singular vectors of L and VT */
01323 /*              by right singular vectors of L */
01324 /*              (Workspace: need M*M+3*M, prefer M*M+2*M+M*NB) */
01325 
01326                 i__2 = *lwork - nwork + 1;
01327                 dormbr_("Q", "L", "N", m, m, m, &work[il], &ldwrkl, &work[
01328                         itauq], &u[u_offset], ldu, &work[nwork], &i__2, &ierr);
01329                 i__2 = *lwork - nwork + 1;
01330                 dormbr_("P", "R", "T", m, m, m, &work[il], &ldwrkl, &work[
01331                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__2, &
01332                         ierr);
01333 
01334 /*              Multiply right singular vectors of L in WORK(IL) by */
01335 /*              Q in A, storing result in VT */
01336 /*              (Workspace: need M*M) */
01337 
01338                 dlacpy_("F", m, m, &vt[vt_offset], ldvt, &work[il], &ldwrkl);
01339                 dgemm_("N", "N", m, n, m, &c_b248, &work[il], &ldwrkl, &a[
01340                         a_offset], lda, &c_b227, &vt[vt_offset], ldvt);
01341 
01342             } else if (wntqa) {
01343 
01344 /*              Path 4t (N much larger than M, JOBZ='A') */
01345 /*              N right singular vectors to be computed in VT and */
01346 /*              M left singular vectors to be computed in U */
01347 
01348                 ivt = 1;
01349 
01350 /*              WORK(IVT) is M by M */
01351 
01352                 ldwkvt = *m;
01353                 itau = ivt + ldwkvt * *m;
01354                 nwork = itau + *m;
01355 
01356 /*              Compute A=L*Q, copying result to VT */
01357 /*              (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */
01358 
01359                 i__2 = *lwork - nwork + 1;
01360                 dgelqf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
01361                         i__2, &ierr);
01362                 dlacpy_("U", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt);
01363 
01364 /*              Generate Q in VT */
01365 /*              (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */
01366 
01367                 i__2 = *lwork - nwork + 1;
01368                 dorglq_(n, n, m, &vt[vt_offset], ldvt, &work[itau], &work[
01369                         nwork], &i__2, &ierr);
01370 
01371 /*              Produce L in A, zeroing out other entries */
01372 
01373                 i__2 = *m - 1;
01374                 i__1 = *m - 1;
01375                 dlaset_("U", &i__2, &i__1, &c_b227, &c_b227, &a[(a_dim1 << 1) 
01376                         + 1], lda);
01377                 ie = itau;
01378                 itauq = ie + *m;
01379                 itaup = itauq + *m;
01380                 nwork = itaup + *m;
01381 
01382 /*              Bidiagonalize L in A */
01383 /*              (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB) */
01384 
01385                 i__2 = *lwork - nwork + 1;
01386                 dgebrd_(m, m, &a[a_offset], lda, &s[1], &work[ie], &work[
01387                         itauq], &work[itaup], &work[nwork], &i__2, &ierr);
01388 
01389 /*              Perform bidiagonal SVD, computing left singular vectors */
01390 /*              of bidiagonal matrix in U and computing right singular */
01391 /*              vectors of bidiagonal matrix in WORK(IVT) */
01392 /*              (Workspace: need M+M*M+BDSPAC) */
01393 
01394                 dbdsdc_("U", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &
01395                         work[ivt], &ldwkvt, dum, idum, &work[nwork], &iwork[1]
01396 , info);
01397 
01398 /*              Overwrite U by left singular vectors of L and WORK(IVT) */
01399 /*              by right singular vectors of L */
01400 /*              (Workspace: need M*M+3*M, prefer M*M+2*M+M*NB) */
01401 
01402                 i__2 = *lwork - nwork + 1;
01403                 dormbr_("Q", "L", "N", m, m, m, &a[a_offset], lda, &work[
01404                         itauq], &u[u_offset], ldu, &work[nwork], &i__2, &ierr);
01405                 i__2 = *lwork - nwork + 1;
01406                 dormbr_("P", "R", "T", m, m, m, &a[a_offset], lda, &work[
01407                         itaup], &work[ivt], &ldwkvt, &work[nwork], &i__2, &
01408                         ierr);
01409 
01410 /*              Multiply right singular vectors of L in WORK(IVT) by */
01411 /*              Q in VT, storing result in A */
01412 /*              (Workspace: need M*M) */
01413 
01414                 dgemm_("N", "N", m, n, m, &c_b248, &work[ivt], &ldwkvt, &vt[
01415                         vt_offset], ldvt, &c_b227, &a[a_offset], lda);
01416 
01417 /*              Copy right singular vectors of A from A to VT */
01418 
01419                 dlacpy_("F", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt);
01420 
01421             }
01422 
01423         } else {
01424 
01425 /*           N .LT. MNTHR */
01426 
01427 /*           Path 5t (N greater than M, but not much larger) */
01428 /*           Reduce to bidiagonal form without LQ decomposition */
01429 
01430             ie = 1;
01431             itauq = ie + *m;
01432             itaup = itauq + *m;
01433             nwork = itaup + *m;
01434 
01435 /*           Bidiagonalize A */
01436 /*           (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB) */
01437 
01438             i__2 = *lwork - nwork + 1;
01439             dgebrd_(m, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &
01440                     work[itaup], &work[nwork], &i__2, &ierr);
01441             if (wntqn) {
01442 
01443 /*              Perform bidiagonal SVD, only computing singular values */
01444 /*              (Workspace: need M+BDSPAC) */
01445 
01446                 dbdsdc_("L", "N", m, &s[1], &work[ie], dum, &c__1, dum, &c__1, 
01447                          dum, idum, &work[nwork], &iwork[1], info);
01448             } else if (wntqo) {
01449                 ldwkvt = *m;
01450                 ivt = nwork;
01451                 if (*lwork >= *m * *n + *m * 3 + bdspac) {
01452 
01453 /*                 WORK( IVT ) is M by N */
01454 
01455                     dlaset_("F", m, n, &c_b227, &c_b227, &work[ivt], &ldwkvt);
01456                     nwork = ivt + ldwkvt * *n;
01457                 } else {
01458 
01459 /*                 WORK( IVT ) is M by M */
01460 
01461                     nwork = ivt + ldwkvt * *m;
01462                     il = nwork;
01463 
01464 /*                 WORK(IL) is M by CHUNK */
01465 
01466                     chunk = (*lwork - *m * *m - *m * 3) / *m;
01467                 }
01468 
01469 /*              Perform bidiagonal SVD, computing left singular vectors */
01470 /*              of bidiagonal matrix in U and computing right singular */
01471 /*              vectors of bidiagonal matrix in WORK(IVT) */
01472 /*              (Workspace: need M*M+BDSPAC) */
01473 
01474                 dbdsdc_("L", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &
01475                         work[ivt], &ldwkvt, dum, idum, &work[nwork], &iwork[1]
01476 , info);
01477 
01478 /*              Overwrite U by left singular vectors of A */
01479 /*              (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */
01480 
01481                 i__2 = *lwork - nwork + 1;
01482                 dormbr_("Q", "L", "N", m, m, n, &a[a_offset], lda, &work[
01483                         itauq], &u[u_offset], ldu, &work[nwork], &i__2, &ierr);
01484 
01485                 if (*lwork >= *m * *n + *m * 3 + bdspac) {
01486 
01487 /*                 Overwrite WORK(IVT) by left singular vectors of A */
01488 /*                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */
01489 
01490                     i__2 = *lwork - nwork + 1;
01491                     dormbr_("P", "R", "T", m, n, m, &a[a_offset], lda, &work[
01492                             itaup], &work[ivt], &ldwkvt, &work[nwork], &i__2, 
01493                             &ierr);
01494 
01495 /*                 Copy right singular vectors of A from WORK(IVT) to A */
01496 
01497                     dlacpy_("F", m, n, &work[ivt], &ldwkvt, &a[a_offset], lda);
01498                 } else {
01499 
01500 /*                 Generate P**T in A */
01501 /*                 (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */
01502 
01503                     i__2 = *lwork - nwork + 1;
01504                     dorgbr_("P", m, n, m, &a[a_offset], lda, &work[itaup], &
01505                             work[nwork], &i__2, &ierr);
01506 
01507 /*                 Multiply Q in A by right singular vectors of */
01508 /*                 bidiagonal matrix in WORK(IVT), storing result in */
01509 /*                 WORK(IL) and copying to A */
01510 /*                 (Workspace: need 2*M*M, prefer M*M+M*N) */
01511 
01512                     i__2 = *n;
01513                     i__1 = chunk;
01514                     for (i__ = 1; i__1 < 0 ? i__ >= i__2 : i__ <= i__2; i__ +=
01515                              i__1) {
01516 /* Computing MIN */
01517                         i__3 = *n - i__ + 1;
01518                         blk = min(i__3,chunk);
01519                         dgemm_("N", "N", m, &blk, m, &c_b248, &work[ivt], &
01520                                 ldwkvt, &a[i__ * a_dim1 + 1], lda, &c_b227, &
01521                                 work[il], m);
01522                         dlacpy_("F", m, &blk, &work[il], m, &a[i__ * a_dim1 + 
01523                                 1], lda);
01524 /* L40: */
01525                     }
01526                 }
01527             } else if (wntqs) {
01528 
01529 /*              Perform bidiagonal SVD, computing left singular vectors */
01530 /*              of bidiagonal matrix in U and computing right singular */
01531 /*              vectors of bidiagonal matrix in VT */
01532 /*              (Workspace: need M+BDSPAC) */
01533 
01534                 dlaset_("F", m, n, &c_b227, &c_b227, &vt[vt_offset], ldvt);
01535                 dbdsdc_("L", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &vt[
01536                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
01537                         info);
01538 
01539 /*              Overwrite U by left singular vectors of A and VT */
01540 /*              by right singular vectors of A */
01541 /*              (Workspace: need 3*M, prefer 2*M+M*NB) */
01542 
01543                 i__1 = *lwork - nwork + 1;
01544                 dormbr_("Q", "L", "N", m, m, n, &a[a_offset], lda, &work[
01545                         itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
01546                 i__1 = *lwork - nwork + 1;
01547                 dormbr_("P", "R", "T", m, n, m, &a[a_offset], lda, &work[
01548                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__1, &
01549                         ierr);
01550             } else if (wntqa) {
01551 
01552 /*              Perform bidiagonal SVD, computing left singular vectors */
01553 /*              of bidiagonal matrix in U and computing right singular */
01554 /*              vectors of bidiagonal matrix in VT */
01555 /*              (Workspace: need M+BDSPAC) */
01556 
01557                 dlaset_("F", n, n, &c_b227, &c_b227, &vt[vt_offset], ldvt);
01558                 dbdsdc_("L", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &vt[
01559                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
01560                         info);
01561 
01562 /*              Set the right corner of VT to identity matrix */
01563 
01564                 if (*n > *m) {
01565                     i__1 = *n - *m;
01566                     i__2 = *n - *m;
01567                     dlaset_("F", &i__1, &i__2, &c_b227, &c_b248, &vt[*m + 1 + 
01568                             (*m + 1) * vt_dim1], ldvt);
01569                 }
01570 
01571 /*              Overwrite U by left singular vectors of A and VT */
01572 /*              by right singular vectors of A */
01573 /*              (Workspace: need 2*M+N, prefer 2*M+N*NB) */
01574 
01575                 i__1 = *lwork - nwork + 1;
01576                 dormbr_("Q", "L", "N", m, m, n, &a[a_offset], lda, &work[
01577                         itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
01578                 i__1 = *lwork - nwork + 1;
01579                 dormbr_("P", "R", "T", n, n, m, &a[a_offset], lda, &work[
01580                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__1, &
01581                         ierr);
01582             }
01583 
01584         }
01585 
01586     }
01587 
01588 /*     Undo scaling if necessary */
01589 
01590     if (iscl == 1) {
01591         if (anrm > bignum) {
01592             dlascl_("G", &c__0, &c__0, &bignum, &anrm, &minmn, &c__1, &s[1], &
01593                     minmn, &ierr);
01594         }
01595         if (anrm < smlnum) {
01596             dlascl_("G", &c__0, &c__0, &smlnum, &anrm, &minmn, &c__1, &s[1], &
01597                     minmn, &ierr);
01598         }
01599     }
01600 
01601 /*     Return optimal workspace in WORK(1) */
01602 
01603     work[1] = (doublereal) maxwrk;
01604 
01605     return 0;
01606 
01607 /*     End of DGESDD */
01608 
01609 } /* dgesdd_ */


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:55:44