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


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:56:07