3 /* Table of constant values */
5 static integer c__1 = 1;
6 static integer c_n1 = -1;
7 static integer c__0 = 0;
8 static real c_b227 = 0.f;
9 static real c_b248 = 1.f;
11 /* Subroutine */ int sgesdd_(char *jobz, integer *m, integer *n, real *a,
12 integer *lda, real *s, real *u, integer *ldu, real *vt, integer *ldvt,
13 real *work, integer *lwork, integer *iwork, integer *info)
15 /* System generated locals */
16 integer a_dim1, a_offset, u_dim1, u_offset, vt_dim1, vt_offset, i__1,
19 /* Builtin functions */
20 double sqrt(doublereal);
23 integer i__, ie, il, ir, iu, blk;
27 integer idum[1], ierr, itau;
28 extern logical lsame_(char *, char *);
30 extern /* Subroutine */ int sgemm_(char *, char *, integer *, integer *,
31 integer *, real *, real *, integer *, real *, integer *, real *,
33 integer minmn, wrkbl, itaup, itauq, mnthr;
36 logical wntqn, wntqo, wntqs;
38 extern /* Subroutine */ int sbdsdc_(char *, char *, integer *, real *,
39 real *, real *, integer *, real *, integer *, real *, integer *,
40 real *, integer *, integer *), sgebrd_(integer *,
41 integer *, real *, integer *, real *, real *, real *, real *,
42 real *, integer *, integer *);
43 extern doublereal slamch_(char *), slange_(char *, integer *,
44 integer *, real *, integer *, real *);
45 extern /* Subroutine */ int xerbla_(char *, integer *);
46 extern integer ilaenv_(integer *, char *, char *, integer *, integer *,
47 integer *, integer *);
49 extern /* Subroutine */ int sgelqf_(integer *, integer *, real *, integer
50 *, real *, real *, integer *, integer *), slascl_(char *, integer
51 *, integer *, real *, real *, integer *, integer *, real *,
52 integer *, integer *), sgeqrf_(integer *, integer *, real
53 *, integer *, real *, real *, integer *, integer *), slacpy_(char
54 *, integer *, integer *, real *, integer *, real *, integer *), slaset_(char *, integer *, integer *, real *, real *,
55 real *, integer *), sorgbr_(char *, integer *, integer *,
56 integer *, real *, integer *, real *, real *, integer *, integer *
59 extern /* Subroutine */ int sormbr_(char *, char *, char *, integer *,
60 integer *, integer *, real *, integer *, real *, real *, integer *
61 , real *, integer *, integer *);
62 integer ldwrkr, minwrk, ldwrku, maxwrk;
63 extern /* Subroutine */ int sorglq_(integer *, integer *, integer *, real
64 *, integer *, real *, real *, integer *, integer *);
68 extern /* Subroutine */ int sorgqr_(integer *, integer *, integer *, real
69 *, integer *, real *, real *, integer *, integer *);
73 /* -- LAPACK driver routine (version 3.1) -- */
74 /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
77 /* .. Scalar Arguments .. */
79 /* .. Array Arguments .. */
85 /* SGESDD computes the singular value decomposition (SVD) of a real */
86 /* M-by-N matrix A, optionally computing the left and right singular */
87 /* vectors. If singular vectors are desired, it uses a */
88 /* divide-and-conquer algorithm. */
90 /* The SVD is written */
92 /* A = U * SIGMA * transpose(V) */
94 /* where SIGMA is an M-by-N matrix which is zero except for its */
95 /* min(m,n) diagonal elements, U is an M-by-M orthogonal matrix, and */
96 /* V is an N-by-N orthogonal matrix. The diagonal elements of SIGMA */
97 /* are the singular values of A; they are real and non-negative, and */
98 /* are returned in descending order. The first min(m,n) columns of */
99 /* U and V are the left and right singular vectors of A. */
101 /* Note that the routine returns VT = V**T, not V. */
103 /* The divide and conquer algorithm makes very mild assumptions about */
104 /* floating point arithmetic. It will work on machines with a guard */
105 /* digit in add/subtract, or on those binary machines without guard */
106 /* digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or */
107 /* Cray-2. It could conceivably fail on hexadecimal or decimal machines */
108 /* without guard digits, but we know of none. */
113 /* JOBZ (input) CHARACTER*1 */
114 /* Specifies options for computing all or part of the matrix U: */
115 /* = 'A': all M columns of U and all N rows of V**T are */
116 /* returned in the arrays U and VT; */
117 /* = 'S': the first min(M,N) columns of U and the first */
118 /* min(M,N) rows of V**T are returned in the arrays U */
120 /* = 'O': If M >= N, the first N columns of U are overwritten */
121 /* on the array A and all rows of V**T are returned in */
123 /* otherwise, all columns of U are returned in the */
124 /* array U and the first M rows of V**T are overwritten */
125 /* in the array A; */
126 /* = 'N': no columns of U or rows of V**T are computed. */
128 /* M (input) INTEGER */
129 /* The number of rows of the input matrix A. M >= 0. */
131 /* N (input) INTEGER */
132 /* The number of columns of the input matrix A. N >= 0. */
134 /* A (input/output) REAL array, dimension (LDA,N) */
135 /* On entry, the M-by-N matrix A. */
137 /* if JOBZ = 'O', A is overwritten with the first N columns */
138 /* of U (the left singular vectors, stored */
139 /* columnwise) if M >= N; */
140 /* A is overwritten with the first M rows */
141 /* of V**T (the right singular vectors, stored */
142 /* rowwise) otherwise. */
143 /* if JOBZ .ne. 'O', the contents of A are destroyed. */
145 /* LDA (input) INTEGER */
146 /* The leading dimension of the array A. LDA >= max(1,M). */
148 /* S (output) REAL array, dimension (min(M,N)) */
149 /* The singular values of A, sorted so that S(i) >= S(i+1). */
151 /* U (output) REAL array, dimension (LDU,UCOL) */
152 /* UCOL = M if JOBZ = 'A' or JOBZ = 'O' and M < N; */
153 /* UCOL = min(M,N) if JOBZ = 'S'. */
154 /* If JOBZ = 'A' or JOBZ = 'O' and M < N, U contains the M-by-M */
155 /* orthogonal matrix U; */
156 /* if JOBZ = 'S', U contains the first min(M,N) columns of U */
157 /* (the left singular vectors, stored columnwise); */
158 /* if JOBZ = 'O' and M >= N, or JOBZ = 'N', U is not referenced. */
160 /* LDU (input) INTEGER */
161 /* The leading dimension of the array U. LDU >= 1; if */
162 /* JOBZ = 'S' or 'A' or JOBZ = 'O' and M < N, LDU >= M. */
164 /* VT (output) REAL array, dimension (LDVT,N) */
165 /* If JOBZ = 'A' or JOBZ = 'O' and M >= N, VT contains the */
166 /* N-by-N orthogonal matrix V**T; */
167 /* if JOBZ = 'S', VT contains the first min(M,N) rows of */
168 /* V**T (the right singular vectors, stored rowwise); */
169 /* if JOBZ = 'O' and M < N, or JOBZ = 'N', VT is not referenced. */
171 /* LDVT (input) INTEGER */
172 /* The leading dimension of the array VT. LDVT >= 1; if */
173 /* JOBZ = 'A' or JOBZ = 'O' and M >= N, LDVT >= N; */
174 /* if JOBZ = 'S', LDVT >= min(M,N). */
176 /* WORK (workspace/output) REAL array, dimension (MAX(1,LWORK)) */
177 /* On exit, if INFO = 0, WORK(1) returns the optimal LWORK; */
179 /* LWORK (input) INTEGER */
180 /* The dimension of the array WORK. LWORK >= 1. */
182 /* LWORK >= 3*min(M,N) + max(max(M,N),6*min(M,N)). */
184 /* LWORK >= 3*min(M,N)*min(M,N) + */
185 /* max(max(M,N),5*min(M,N)*min(M,N)+4*min(M,N)). */
186 /* If JOBZ = 'S' or 'A' */
187 /* LWORK >= 3*min(M,N)*min(M,N) + */
188 /* max(max(M,N),4*min(M,N)*min(M,N)+4*min(M,N)). */
189 /* For good performance, LWORK should generally be larger. */
190 /* If LWORK = -1 but other input arguments are legal, WORK(1) */
191 /* returns the optimal LWORK. */
193 /* IWORK (workspace) INTEGER array, dimension (8*min(M,N)) */
195 /* INFO (output) INTEGER */
196 /* = 0: successful exit. */
197 /* < 0: if INFO = -i, the i-th argument had an illegal value. */
198 /* > 0: SBDSDC did not converge, updating process failed. */
200 /* Further Details */
201 /* =============== */
203 /* Based on contributions by */
204 /* Ming Gu and Huan Ren, Computer Science Division, University of */
205 /* California at Berkeley, USA */
207 /* ===================================================================== */
209 /* .. Parameters .. */
211 /* .. Local Scalars .. */
213 /* .. Local Arrays .. */
215 /* .. External Subroutines .. */
217 /* .. External Functions .. */
219 /* .. Intrinsic Functions .. */
221 /* .. Executable Statements .. */
223 /* Test the input arguments */
225 /* Parameter adjustments */
227 a_offset = 1 + a_dim1;
231 u_offset = 1 + u_dim1;
234 vt_offset = 1 + vt_dim1;
242 wntqa = lsame_(jobz, "A");
243 wntqs = lsame_(jobz, "S");
244 wntqas = wntqa || wntqs;
245 wntqo = lsame_(jobz, "O");
246 wntqn = lsame_(jobz, "N");
247 lquery = *lwork == -1;
249 if (! (wntqa || wntqs || wntqo || wntqn)) {
255 } else if (*lda < max(1,*m)) {
257 } else if (*ldu < 1 || wntqas && *ldu < *m || wntqo && *m < *n && *ldu < *
260 } else if (*ldvt < 1 || wntqa && *ldvt < *n || wntqs && *ldvt < minmn ||
261 wntqo && *m >= *n && *ldvt < *n) {
265 /* Compute workspace */
266 /* (Note: Comments in the code beginning "Workspace:" describe the */
267 /* minimal amount of workspace needed at that point in the code, */
268 /* as well as the preferred amount for good performance. */
269 /* NB refers to the optimal block size for the immediately */
270 /* following subroutine, as returned by ILAENV.) */
275 if (*m >= *n && minmn > 0) {
277 /* Compute space needed for SBDSDC */
279 mnthr = (integer) (minmn * 11.f / 6.f);
283 bdspac = *n * 3 * *n + (*n << 2);
288 /* Path 1 (M much larger than N, JOBZ='N') */
290 wrkbl = *n + *n * ilaenv_(&c__1, "SGEQRF", " ", m, n, &
293 i__1 = wrkbl, i__2 = *n * 3 + (*n << 1) * ilaenv_(&c__1,
294 "SGEBRD", " ", n, n, &c_n1, &c_n1);
295 wrkbl = max(i__1,i__2);
297 i__1 = wrkbl, i__2 = bdspac + *n;
298 maxwrk = max(i__1,i__2);
299 minwrk = bdspac + *n;
302 /* Path 2 (M much larger than N, JOBZ='O') */
304 wrkbl = *n + *n * ilaenv_(&c__1, "SGEQRF", " ", m, n, &
307 i__1 = wrkbl, i__2 = *n + *n * ilaenv_(&c__1, "SORGQR",
308 " ", m, n, n, &c_n1);
309 wrkbl = max(i__1,i__2);
311 i__1 = wrkbl, i__2 = *n * 3 + (*n << 1) * ilaenv_(&c__1,
312 "SGEBRD", " ", n, n, &c_n1, &c_n1);
313 wrkbl = max(i__1,i__2);
315 i__1 = wrkbl, i__2 = *n * 3 + *n * ilaenv_(&c__1, "SORMBR"
316 , "QLN", n, n, n, &c_n1);
317 wrkbl = max(i__1,i__2);
319 i__1 = wrkbl, i__2 = *n * 3 + *n * ilaenv_(&c__1, "SORMBR"
320 , "PRT", n, n, n, &c_n1);
321 wrkbl = max(i__1,i__2);
323 i__1 = wrkbl, i__2 = bdspac + *n * 3;
324 wrkbl = max(i__1,i__2);
325 maxwrk = wrkbl + (*n << 1) * *n;
326 minwrk = bdspac + (*n << 1) * *n + *n * 3;
329 /* Path 3 (M much larger than N, JOBZ='S') */
331 wrkbl = *n + *n * ilaenv_(&c__1, "SGEQRF", " ", m, n, &
334 i__1 = wrkbl, i__2 = *n + *n * ilaenv_(&c__1, "SORGQR",
335 " ", m, n, n, &c_n1);
336 wrkbl = max(i__1,i__2);
338 i__1 = wrkbl, i__2 = *n * 3 + (*n << 1) * ilaenv_(&c__1,
339 "SGEBRD", " ", n, n, &c_n1, &c_n1);
340 wrkbl = max(i__1,i__2);
342 i__1 = wrkbl, i__2 = *n * 3 + *n * ilaenv_(&c__1, "SORMBR"
343 , "QLN", n, n, n, &c_n1);
344 wrkbl = max(i__1,i__2);
346 i__1 = wrkbl, i__2 = *n * 3 + *n * ilaenv_(&c__1, "SORMBR"
347 , "PRT", n, n, n, &c_n1);
348 wrkbl = max(i__1,i__2);
350 i__1 = wrkbl, i__2 = bdspac + *n * 3;
351 wrkbl = max(i__1,i__2);
352 maxwrk = wrkbl + *n * *n;
353 minwrk = bdspac + *n * *n + *n * 3;
356 /* Path 4 (M much larger than N, JOBZ='A') */
358 wrkbl = *n + *n * ilaenv_(&c__1, "SGEQRF", " ", m, n, &
361 i__1 = wrkbl, i__2 = *n + *m * ilaenv_(&c__1, "SORGQR",
362 " ", m, m, n, &c_n1);
363 wrkbl = max(i__1,i__2);
365 i__1 = wrkbl, i__2 = *n * 3 + (*n << 1) * ilaenv_(&c__1,
366 "SGEBRD", " ", n, n, &c_n1, &c_n1);
367 wrkbl = max(i__1,i__2);
369 i__1 = wrkbl, i__2 = *n * 3 + *n * ilaenv_(&c__1, "SORMBR"
370 , "QLN", n, n, n, &c_n1);
371 wrkbl = max(i__1,i__2);
373 i__1 = wrkbl, i__2 = *n * 3 + *n * ilaenv_(&c__1, "SORMBR"
374 , "PRT", n, n, n, &c_n1);
375 wrkbl = max(i__1,i__2);
377 i__1 = wrkbl, i__2 = bdspac + *n * 3;
378 wrkbl = max(i__1,i__2);
379 maxwrk = wrkbl + *n * *n;
380 minwrk = bdspac + *n * *n + *n * 3;
384 /* Path 5 (M at least N, but not much larger) */
386 wrkbl = *n * 3 + (*m + *n) * ilaenv_(&c__1, "SGEBRD", " ", m,
390 i__1 = wrkbl, i__2 = bdspac + *n * 3;
391 maxwrk = max(i__1,i__2);
392 minwrk = *n * 3 + max(*m,bdspac);
395 i__1 = wrkbl, i__2 = *n * 3 + *n * ilaenv_(&c__1, "SORMBR"
396 , "QLN", m, n, n, &c_n1);
397 wrkbl = max(i__1,i__2);
399 i__1 = wrkbl, i__2 = *n * 3 + *n * ilaenv_(&c__1, "SORMBR"
400 , "PRT", n, n, n, &c_n1);
401 wrkbl = max(i__1,i__2);
403 i__1 = wrkbl, i__2 = bdspac + *n * 3;
404 wrkbl = max(i__1,i__2);
405 maxwrk = wrkbl + *m * *n;
407 i__1 = *m, i__2 = *n * *n + bdspac;
408 minwrk = *n * 3 + max(i__1,i__2);
411 i__1 = wrkbl, i__2 = *n * 3 + *n * ilaenv_(&c__1, "SORMBR"
412 , "QLN", m, n, n, &c_n1);
413 wrkbl = max(i__1,i__2);
415 i__1 = wrkbl, i__2 = *n * 3 + *n * ilaenv_(&c__1, "SORMBR"
416 , "PRT", n, n, n, &c_n1);
417 wrkbl = max(i__1,i__2);
419 i__1 = wrkbl, i__2 = bdspac + *n * 3;
420 maxwrk = max(i__1,i__2);
421 minwrk = *n * 3 + max(*m,bdspac);
424 i__1 = wrkbl, i__2 = *n * 3 + *m * ilaenv_(&c__1, "SORMBR"
425 , "QLN", m, m, n, &c_n1);
426 wrkbl = max(i__1,i__2);
428 i__1 = wrkbl, i__2 = *n * 3 + *n * ilaenv_(&c__1, "SORMBR"
429 , "PRT", n, n, n, &c_n1);
430 wrkbl = max(i__1,i__2);
432 i__1 = maxwrk, i__2 = bdspac + *n * 3;
433 maxwrk = max(i__1,i__2);
434 minwrk = *n * 3 + max(*m,bdspac);
437 } else if (minmn > 0) {
439 /* Compute space needed for SBDSDC */
441 mnthr = (integer) (minmn * 11.f / 6.f);
445 bdspac = *m * 3 * *m + (*m << 2);
450 /* Path 1t (N much larger than M, JOBZ='N') */
452 wrkbl = *m + *m * ilaenv_(&c__1, "SGELQF", " ", m, n, &
455 i__1 = wrkbl, i__2 = *m * 3 + (*m << 1) * ilaenv_(&c__1,
456 "SGEBRD", " ", m, m, &c_n1, &c_n1);
457 wrkbl = max(i__1,i__2);
459 i__1 = wrkbl, i__2 = bdspac + *m;
460 maxwrk = max(i__1,i__2);
461 minwrk = bdspac + *m;
464 /* Path 2t (N much larger than M, JOBZ='O') */
466 wrkbl = *m + *m * ilaenv_(&c__1, "SGELQF", " ", m, n, &
469 i__1 = wrkbl, i__2 = *m + *m * ilaenv_(&c__1, "SORGLQ",
470 " ", m, n, m, &c_n1);
471 wrkbl = max(i__1,i__2);
473 i__1 = wrkbl, i__2 = *m * 3 + (*m << 1) * ilaenv_(&c__1,
474 "SGEBRD", " ", m, m, &c_n1, &c_n1);
475 wrkbl = max(i__1,i__2);
477 i__1 = wrkbl, i__2 = *m * 3 + *m * ilaenv_(&c__1, "SORMBR"
478 , "QLN", m, m, m, &c_n1);
479 wrkbl = max(i__1,i__2);
481 i__1 = wrkbl, i__2 = *m * 3 + *m * ilaenv_(&c__1, "SORMBR"
482 , "PRT", m, m, m, &c_n1);
483 wrkbl = max(i__1,i__2);
485 i__1 = wrkbl, i__2 = bdspac + *m * 3;
486 wrkbl = max(i__1,i__2);
487 maxwrk = wrkbl + (*m << 1) * *m;
488 minwrk = bdspac + (*m << 1) * *m + *m * 3;
491 /* Path 3t (N much larger than M, JOBZ='S') */
493 wrkbl = *m + *m * ilaenv_(&c__1, "SGELQF", " ", m, n, &
496 i__1 = wrkbl, i__2 = *m + *m * ilaenv_(&c__1, "SORGLQ",
497 " ", m, n, m, &c_n1);
498 wrkbl = max(i__1,i__2);
500 i__1 = wrkbl, i__2 = *m * 3 + (*m << 1) * ilaenv_(&c__1,
501 "SGEBRD", " ", m, m, &c_n1, &c_n1);
502 wrkbl = max(i__1,i__2);
504 i__1 = wrkbl, i__2 = *m * 3 + *m * ilaenv_(&c__1, "SORMBR"
505 , "QLN", m, m, m, &c_n1);
506 wrkbl = max(i__1,i__2);
508 i__1 = wrkbl, i__2 = *m * 3 + *m * ilaenv_(&c__1, "SORMBR"
509 , "PRT", m, m, m, &c_n1);
510 wrkbl = max(i__1,i__2);
512 i__1 = wrkbl, i__2 = bdspac + *m * 3;
513 wrkbl = max(i__1,i__2);
514 maxwrk = wrkbl + *m * *m;
515 minwrk = bdspac + *m * *m + *m * 3;
518 /* Path 4t (N much larger than M, JOBZ='A') */
520 wrkbl = *m + *m * ilaenv_(&c__1, "SGELQF", " ", m, n, &
523 i__1 = wrkbl, i__2 = *m + *n * ilaenv_(&c__1, "SORGLQ",
524 " ", n, n, m, &c_n1);
525 wrkbl = max(i__1,i__2);
527 i__1 = wrkbl, i__2 = *m * 3 + (*m << 1) * ilaenv_(&c__1,
528 "SGEBRD", " ", m, m, &c_n1, &c_n1);
529 wrkbl = max(i__1,i__2);
531 i__1 = wrkbl, i__2 = *m * 3 + *m * ilaenv_(&c__1, "SORMBR"
532 , "QLN", m, m, m, &c_n1);
533 wrkbl = max(i__1,i__2);
535 i__1 = wrkbl, i__2 = *m * 3 + *m * ilaenv_(&c__1, "SORMBR"
536 , "PRT", m, m, m, &c_n1);
537 wrkbl = max(i__1,i__2);
539 i__1 = wrkbl, i__2 = bdspac + *m * 3;
540 wrkbl = max(i__1,i__2);
541 maxwrk = wrkbl + *m * *m;
542 minwrk = bdspac + *m * *m + *m * 3;
546 /* Path 5t (N greater than M, but not much larger) */
548 wrkbl = *m * 3 + (*m + *n) * ilaenv_(&c__1, "SGEBRD", " ", m,
552 i__1 = wrkbl, i__2 = bdspac + *m * 3;
553 maxwrk = max(i__1,i__2);
554 minwrk = *m * 3 + max(*n,bdspac);
557 i__1 = wrkbl, i__2 = *m * 3 + *m * ilaenv_(&c__1, "SORMBR"
558 , "QLN", m, m, n, &c_n1);
559 wrkbl = max(i__1,i__2);
561 i__1 = wrkbl, i__2 = *m * 3 + *m * ilaenv_(&c__1, "SORMBR"
562 , "PRT", m, n, m, &c_n1);
563 wrkbl = max(i__1,i__2);
565 i__1 = wrkbl, i__2 = bdspac + *m * 3;
566 wrkbl = max(i__1,i__2);
567 maxwrk = wrkbl + *m * *n;
569 i__1 = *n, i__2 = *m * *m + bdspac;
570 minwrk = *m * 3 + max(i__1,i__2);
573 i__1 = wrkbl, i__2 = *m * 3 + *m * ilaenv_(&c__1, "SORMBR"
574 , "QLN", m, m, n, &c_n1);
575 wrkbl = max(i__1,i__2);
577 i__1 = wrkbl, i__2 = *m * 3 + *m * ilaenv_(&c__1, "SORMBR"
578 , "PRT", m, n, m, &c_n1);
579 wrkbl = max(i__1,i__2);
581 i__1 = wrkbl, i__2 = bdspac + *m * 3;
582 maxwrk = max(i__1,i__2);
583 minwrk = *m * 3 + max(*n,bdspac);
586 i__1 = wrkbl, i__2 = *m * 3 + *m * ilaenv_(&c__1, "SORMBR"
587 , "QLN", m, m, n, &c_n1);
588 wrkbl = max(i__1,i__2);
590 i__1 = wrkbl, i__2 = *m * 3 + *m * ilaenv_(&c__1, "SORMBR"
591 , "PRT", n, n, m, &c_n1);
592 wrkbl = max(i__1,i__2);
594 i__1 = wrkbl, i__2 = bdspac + *m * 3;
595 maxwrk = max(i__1,i__2);
596 minwrk = *m * 3 + max(*n,bdspac);
600 maxwrk = max(maxwrk,minwrk);
601 work[1] = (real) maxwrk;
603 if (*lwork < minwrk && ! lquery) {
610 xerbla_("SGESDD", &i__1);
616 /* Quick return if possible */
618 if (*m == 0 || *n == 0) {
622 /* Get machine constants */
625 smlnum = sqrt(slamch_("S")) / eps;
626 bignum = 1.f / smlnum;
628 /* Scale A if max element outside range [SMLNUM,BIGNUM] */
630 anrm = slange_("M", m, n, &a[a_offset], lda, dum);
632 if (anrm > 0.f && anrm < smlnum) {
634 slascl_("G", &c__0, &c__0, &anrm, &smlnum, m, n, &a[a_offset], lda, &
636 } else if (anrm > bignum) {
638 slascl_("G", &c__0, &c__0, &anrm, &bignum, m, n, &a[a_offset], lda, &
644 /* A has at least as many rows as columns. If A has sufficiently */
645 /* more rows than columns, first reduce using the QR */
646 /* decomposition (if sufficient workspace available) */
652 /* Path 1 (M much larger than N, JOBZ='N') */
653 /* No singular vectors to be computed */
659 /* (Workspace: need 2*N, prefer N+N*NB) */
661 i__1 = *lwork - nwork + 1;
662 sgeqrf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
665 /* Zero out below R */
669 slaset_("L", &i__1, &i__2, &c_b227, &c_b227, &a[a_dim1 + 2],
676 /* Bidiagonalize R in A */
677 /* (Workspace: need 4*N, prefer 3*N+2*N*NB) */
679 i__1 = *lwork - nwork + 1;
680 sgebrd_(n, n, &a[a_offset], lda, &s[1], &work[ie], &work[
681 itauq], &work[itaup], &work[nwork], &i__1, &ierr);
684 /* Perform bidiagonal SVD, computing singular values only */
685 /* (Workspace: need N+BDSPAC) */
687 sbdsdc_("U", "N", n, &s[1], &work[ie], dum, &c__1, dum, &c__1,
688 dum, idum, &work[nwork], &iwork[1], info);
692 /* Path 2 (M much larger than N, JOBZ = 'O') */
693 /* N left singular vectors to be overwritten on A and */
694 /* N right singular vectors to be computed in VT */
698 /* WORK(IR) is LDWRKR by N */
700 if (*lwork >= *lda * *n + *n * *n + *n * 3 + bdspac) {
703 ldwrkr = (*lwork - *n * *n - *n * 3 - bdspac) / *n;
705 itau = ir + ldwrkr * *n;
709 /* (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */
711 i__1 = *lwork - nwork + 1;
712 sgeqrf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
715 /* Copy R to WORK(IR), zeroing out below it */
717 slacpy_("U", n, n, &a[a_offset], lda, &work[ir], &ldwrkr);
720 slaset_("L", &i__1, &i__2, &c_b227, &c_b227, &work[ir + 1], &
723 /* Generate Q in A */
724 /* (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */
726 i__1 = *lwork - nwork + 1;
727 sorgqr_(m, n, n, &a[a_offset], lda, &work[itau], &work[nwork],
734 /* Bidiagonalize R in VT, copying result to WORK(IR) */
735 /* (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB) */
737 i__1 = *lwork - nwork + 1;
738 sgebrd_(n, n, &work[ir], &ldwrkr, &s[1], &work[ie], &work[
739 itauq], &work[itaup], &work[nwork], &i__1, &ierr);
741 /* WORK(IU) is N by N */
744 nwork = iu + *n * *n;
746 /* Perform bidiagonal SVD, computing left singular vectors */
747 /* of bidiagonal matrix in WORK(IU) and computing right */
748 /* singular vectors of bidiagonal matrix in VT */
749 /* (Workspace: need N+N*N+BDSPAC) */
751 sbdsdc_("U", "I", n, &s[1], &work[ie], &work[iu], n, &vt[
752 vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1],
755 /* Overwrite WORK(IU) by left singular vectors of R */
756 /* and VT by right singular vectors of R */
757 /* (Workspace: need 2*N*N+3*N, prefer 2*N*N+2*N+N*NB) */
759 i__1 = *lwork - nwork + 1;
760 sormbr_("Q", "L", "N", n, n, n, &work[ir], &ldwrkr, &work[
761 itauq], &work[iu], n, &work[nwork], &i__1, &ierr);
762 i__1 = *lwork - nwork + 1;
763 sormbr_("P", "R", "T", n, n, n, &work[ir], &ldwrkr, &work[
764 itaup], &vt[vt_offset], ldvt, &work[nwork], &i__1, &
767 /* Multiply Q in A by left singular vectors of R in */
768 /* WORK(IU), storing result in WORK(IR) and copying to A */
769 /* (Workspace: need 2*N*N, prefer N*N+M*N) */
773 for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ +=
777 chunk = min(i__3,ldwrkr);
778 sgemm_("N", "N", &chunk, n, n, &c_b248, &a[i__ + a_dim1],
779 lda, &work[iu], n, &c_b227, &work[ir], &ldwrkr);
780 slacpy_("F", &chunk, n, &work[ir], &ldwrkr, &a[i__ +
787 /* Path 3 (M much larger than N, JOBZ='S') */
788 /* N left singular vectors to be computed in U and */
789 /* N right singular vectors to be computed in VT */
793 /* WORK(IR) is N by N */
796 itau = ir + ldwrkr * *n;
800 /* (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */
802 i__2 = *lwork - nwork + 1;
803 sgeqrf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
806 /* Copy R to WORK(IR), zeroing out below it */
808 slacpy_("U", n, n, &a[a_offset], lda, &work[ir], &ldwrkr);
811 slaset_("L", &i__2, &i__1, &c_b227, &c_b227, &work[ir + 1], &
814 /* Generate Q in A */
815 /* (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */
817 i__2 = *lwork - nwork + 1;
818 sorgqr_(m, n, n, &a[a_offset], lda, &work[itau], &work[nwork],
825 /* Bidiagonalize R in WORK(IR) */
826 /* (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB) */
828 i__2 = *lwork - nwork + 1;
829 sgebrd_(n, n, &work[ir], &ldwrkr, &s[1], &work[ie], &work[
830 itauq], &work[itaup], &work[nwork], &i__2, &ierr);
832 /* Perform bidiagonal SVD, computing left singular vectors */
833 /* of bidiagoal matrix in U and computing right singular */
834 /* vectors of bidiagonal matrix in VT */
835 /* (Workspace: need N+BDSPAC) */
837 sbdsdc_("U", "I", n, &s[1], &work[ie], &u[u_offset], ldu, &vt[
838 vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1],
841 /* Overwrite U by left singular vectors of R and VT */
842 /* by right singular vectors of R */
843 /* (Workspace: need N*N+3*N, prefer N*N+2*N+N*NB) */
845 i__2 = *lwork - nwork + 1;
846 sormbr_("Q", "L", "N", n, n, n, &work[ir], &ldwrkr, &work[
847 itauq], &u[u_offset], ldu, &work[nwork], &i__2, &ierr);
849 i__2 = *lwork - nwork + 1;
850 sormbr_("P", "R", "T", n, n, n, &work[ir], &ldwrkr, &work[
851 itaup], &vt[vt_offset], ldvt, &work[nwork], &i__2, &
854 /* Multiply Q in A by left singular vectors of R in */
855 /* WORK(IR), storing result in U */
856 /* (Workspace: need N*N) */
858 slacpy_("F", n, n, &u[u_offset], ldu, &work[ir], &ldwrkr);
859 sgemm_("N", "N", m, n, n, &c_b248, &a[a_offset], lda, &work[
860 ir], &ldwrkr, &c_b227, &u[u_offset], ldu);
864 /* Path 4 (M much larger than N, JOBZ='A') */
865 /* M left singular vectors to be computed in U and */
866 /* N right singular vectors to be computed in VT */
870 /* WORK(IU) is N by N */
873 itau = iu + ldwrku * *n;
876 /* Compute A=Q*R, copying result to U */
877 /* (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */
879 i__2 = *lwork - nwork + 1;
880 sgeqrf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
882 slacpy_("L", m, n, &a[a_offset], lda, &u[u_offset], ldu);
884 /* Generate Q in U */
885 /* (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */
886 i__2 = *lwork - nwork + 1;
887 sorgqr_(m, m, n, &u[u_offset], ldu, &work[itau], &work[nwork],
890 /* Produce R in A, zeroing out other entries */
894 slaset_("L", &i__2, &i__1, &c_b227, &c_b227, &a[a_dim1 + 2],
901 /* Bidiagonalize R in A */
902 /* (Workspace: need N*N+4*N, prefer N*N+3*N+2*N*NB) */
904 i__2 = *lwork - nwork + 1;
905 sgebrd_(n, n, &a[a_offset], lda, &s[1], &work[ie], &work[
906 itauq], &work[itaup], &work[nwork], &i__2, &ierr);
908 /* Perform bidiagonal SVD, computing left singular vectors */
909 /* of bidiagonal matrix in WORK(IU) and computing right */
910 /* singular vectors of bidiagonal matrix in VT */
911 /* (Workspace: need N+N*N+BDSPAC) */
913 sbdsdc_("U", "I", n, &s[1], &work[ie], &work[iu], n, &vt[
914 vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1],
917 /* Overwrite WORK(IU) by left singular vectors of R and VT */
918 /* by right singular vectors of R */
919 /* (Workspace: need N*N+3*N, prefer N*N+2*N+N*NB) */
921 i__2 = *lwork - nwork + 1;
922 sormbr_("Q", "L", "N", n, n, n, &a[a_offset], lda, &work[
923 itauq], &work[iu], &ldwrku, &work[nwork], &i__2, &
925 i__2 = *lwork - nwork + 1;
926 sormbr_("P", "R", "T", n, n, n, &a[a_offset], lda, &work[
927 itaup], &vt[vt_offset], ldvt, &work[nwork], &i__2, &
930 /* Multiply Q in U by left singular vectors of R in */
931 /* WORK(IU), storing result in A */
932 /* (Workspace: need N*N) */
934 sgemm_("N", "N", m, n, n, &c_b248, &u[u_offset], ldu, &work[
935 iu], &ldwrku, &c_b227, &a[a_offset], lda);
937 /* Copy left singular vectors of A from A to U */
939 slacpy_("F", m, n, &a[a_offset], lda, &u[u_offset], ldu);
947 /* Path 5 (M at least N, but not much larger) */
948 /* Reduce to bidiagonal form without QR decomposition */
955 /* Bidiagonalize A */
956 /* (Workspace: need 3*N+M, prefer 3*N+(M+N)*NB) */
958 i__2 = *lwork - nwork + 1;
959 sgebrd_(m, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &
960 work[itaup], &work[nwork], &i__2, &ierr);
963 /* Perform bidiagonal SVD, only computing singular values */
964 /* (Workspace: need N+BDSPAC) */
966 sbdsdc_("U", "N", n, &s[1], &work[ie], dum, &c__1, dum, &c__1,
967 dum, idum, &work[nwork], &iwork[1], info);
970 if (*lwork >= *m * *n + *n * 3 + bdspac) {
972 /* WORK( IU ) is M by N */
975 nwork = iu + ldwrku * *n;
976 slaset_("F", m, n, &c_b227, &c_b227, &work[iu], &ldwrku);
979 /* WORK( IU ) is N by N */
982 nwork = iu + ldwrku * *n;
984 /* WORK(IR) is LDWRKR by N */
987 ldwrkr = (*lwork - *n * *n - *n * 3) / *n;
989 nwork = iu + ldwrku * *n;
991 /* Perform bidiagonal SVD, computing left singular vectors */
992 /* of bidiagonal matrix in WORK(IU) and computing right */
993 /* singular vectors of bidiagonal matrix in VT */
994 /* (Workspace: need N+N*N+BDSPAC) */
996 sbdsdc_("U", "I", n, &s[1], &work[ie], &work[iu], &ldwrku, &
997 vt[vt_offset], ldvt, dum, idum, &work[nwork], &iwork[
1000 /* Overwrite VT by right singular vectors of A */
1001 /* (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */
1003 i__2 = *lwork - nwork + 1;
1004 sormbr_("P", "R", "T", n, n, n, &a[a_offset], lda, &work[
1005 itaup], &vt[vt_offset], ldvt, &work[nwork], &i__2, &
1008 if (*lwork >= *m * *n + *n * 3 + bdspac) {
1010 /* Overwrite WORK(IU) by left singular vectors of A */
1011 /* (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */
1013 i__2 = *lwork - nwork + 1;
1014 sormbr_("Q", "L", "N", m, n, n, &a[a_offset], lda, &work[
1015 itauq], &work[iu], &ldwrku, &work[nwork], &i__2, &
1018 /* Copy left singular vectors of A from WORK(IU) to A */
1020 slacpy_("F", m, n, &work[iu], &ldwrku, &a[a_offset], lda);
1023 /* Generate Q in A */
1024 /* (Workspace: need N*N+2*N, prefer N*N+N+N*NB) */
1026 i__2 = *lwork - nwork + 1;
1027 sorgbr_("Q", m, n, n, &a[a_offset], lda, &work[itauq], &
1028 work[nwork], &i__2, &ierr);
1030 /* Multiply Q in A by left singular vectors of */
1031 /* bidiagonal matrix in WORK(IU), storing result in */
1032 /* WORK(IR) and copying to A */
1033 /* (Workspace: need 2*N*N, prefer N*N+M*N) */
1037 for (i__ = 1; i__1 < 0 ? i__ >= i__2 : i__ <= i__2; i__ +=
1040 i__3 = *m - i__ + 1;
1041 chunk = min(i__3,ldwrkr);
1042 sgemm_("N", "N", &chunk, n, n, &c_b248, &a[i__ +
1043 a_dim1], lda, &work[iu], &ldwrku, &c_b227, &
1045 slacpy_("F", &chunk, n, &work[ir], &ldwrkr, &a[i__ +
1053 /* Perform bidiagonal SVD, computing left singular vectors */
1054 /* of bidiagonal matrix in U and computing right singular */
1055 /* vectors of bidiagonal matrix in VT */
1056 /* (Workspace: need N+BDSPAC) */
1058 slaset_("F", m, n, &c_b227, &c_b227, &u[u_offset], ldu);
1059 sbdsdc_("U", "I", n, &s[1], &work[ie], &u[u_offset], ldu, &vt[
1060 vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1],
1063 /* Overwrite U by left singular vectors of A and VT */
1064 /* by right singular vectors of A */
1065 /* (Workspace: need 3*N, prefer 2*N+N*NB) */
1067 i__1 = *lwork - nwork + 1;
1068 sormbr_("Q", "L", "N", m, n, n, &a[a_offset], lda, &work[
1069 itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
1070 i__1 = *lwork - nwork + 1;
1071 sormbr_("P", "R", "T", n, n, n, &a[a_offset], lda, &work[
1072 itaup], &vt[vt_offset], ldvt, &work[nwork], &i__1, &
1076 /* Perform bidiagonal SVD, computing left singular vectors */
1077 /* of bidiagonal matrix in U and computing right singular */
1078 /* vectors of bidiagonal matrix in VT */
1079 /* (Workspace: need N+BDSPAC) */
1081 slaset_("F", m, m, &c_b227, &c_b227, &u[u_offset], ldu);
1082 sbdsdc_("U", "I", n, &s[1], &work[ie], &u[u_offset], ldu, &vt[
1083 vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1],
1086 /* Set the right corner of U to identity matrix */
1091 slaset_("F", &i__1, &i__2, &c_b227, &c_b248, &u[*n + 1 + (
1092 *n + 1) * u_dim1], ldu);
1095 /* Overwrite U by left singular vectors of A and VT */
1096 /* by right singular vectors of A */
1097 /* (Workspace: need N*N+2*N+M, prefer N*N+2*N+M*NB) */
1099 i__1 = *lwork - nwork + 1;
1100 sormbr_("Q", "L", "N", m, m, n, &a[a_offset], lda, &work[
1101 itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
1102 i__1 = *lwork - nwork + 1;
1103 sormbr_("P", "R", "T", n, n, m, &a[a_offset], lda, &work[
1104 itaup], &vt[vt_offset], ldvt, &work[nwork], &i__1, &
1112 /* A has more columns than rows. If A has sufficiently more */
1113 /* columns than rows, first reduce using the LQ decomposition (if */
1114 /* sufficient workspace available) */
1120 /* Path 1t (N much larger than M, JOBZ='N') */
1121 /* No singular vectors to be computed */
1127 /* (Workspace: need 2*M, prefer M+M*NB) */
1129 i__1 = *lwork - nwork + 1;
1130 sgelqf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
1133 /* Zero out above L */
1137 slaset_("U", &i__1, &i__2, &c_b227, &c_b227, &a[(a_dim1 << 1)
1144 /* Bidiagonalize L in A */
1145 /* (Workspace: need 4*M, prefer 3*M+2*M*NB) */
1147 i__1 = *lwork - nwork + 1;
1148 sgebrd_(m, m, &a[a_offset], lda, &s[1], &work[ie], &work[
1149 itauq], &work[itaup], &work[nwork], &i__1, &ierr);
1152 /* Perform bidiagonal SVD, computing singular values only */
1153 /* (Workspace: need M+BDSPAC) */
1155 sbdsdc_("U", "N", m, &s[1], &work[ie], dum, &c__1, dum, &c__1,
1156 dum, idum, &work[nwork], &iwork[1], info);
1160 /* Path 2t (N much larger than M, JOBZ='O') */
1161 /* M right singular vectors to be overwritten on A and */
1162 /* M left singular vectors to be computed in U */
1169 if (*lwork >= *m * *n + *m * *m + *m * 3 + bdspac) {
1171 /* WORK(IL) is M by N */
1177 chunk = (*lwork - *m * *m) / *m;
1179 itau = il + ldwrkl * *m;
1183 /* (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */
1185 i__1 = *lwork - nwork + 1;
1186 sgelqf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
1189 /* Copy L to WORK(IL), zeroing about above it */
1191 slacpy_("L", m, m, &a[a_offset], lda, &work[il], &ldwrkl);
1194 slaset_("U", &i__1, &i__2, &c_b227, &c_b227, &work[il +
1197 /* Generate Q in A */
1198 /* (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */
1200 i__1 = *lwork - nwork + 1;
1201 sorglq_(m, n, m, &a[a_offset], lda, &work[itau], &work[nwork],
1208 /* Bidiagonalize L in WORK(IL) */
1209 /* (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB) */
1211 i__1 = *lwork - nwork + 1;
1212 sgebrd_(m, m, &work[il], &ldwrkl, &s[1], &work[ie], &work[
1213 itauq], &work[itaup], &work[nwork], &i__1, &ierr);
1215 /* Perform bidiagonal SVD, computing left singular vectors */
1216 /* of bidiagonal matrix in U, and computing right singular */
1217 /* vectors of bidiagonal matrix in WORK(IVT) */
1218 /* (Workspace: need M+M*M+BDSPAC) */
1220 sbdsdc_("U", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &
1221 work[ivt], m, dum, idum, &work[nwork], &iwork[1],
1224 /* Overwrite U by left singular vectors of L and WORK(IVT) */
1225 /* by right singular vectors of L */
1226 /* (Workspace: need 2*M*M+3*M, prefer 2*M*M+2*M+M*NB) */
1228 i__1 = *lwork - nwork + 1;
1229 sormbr_("Q", "L", "N", m, m, m, &work[il], &ldwrkl, &work[
1230 itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
1231 i__1 = *lwork - nwork + 1;
1232 sormbr_("P", "R", "T", m, m, m, &work[il], &ldwrkl, &work[
1233 itaup], &work[ivt], m, &work[nwork], &i__1, &ierr);
1235 /* Multiply right singular vectors of L in WORK(IVT) by Q */
1236 /* in A, storing result in WORK(IL) and copying to A */
1237 /* (Workspace: need 2*M*M, prefer M*M+M*N) */
1241 for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ +=
1244 i__3 = *n - i__ + 1;
1245 blk = min(i__3,chunk);
1246 sgemm_("N", "N", m, &blk, m, &c_b248, &work[ivt], m, &a[
1247 i__ * a_dim1 + 1], lda, &c_b227, &work[il], &
1249 slacpy_("F", m, &blk, &work[il], &ldwrkl, &a[i__ * a_dim1
1256 /* Path 3t (N much larger than M, JOBZ='S') */
1257 /* M right singular vectors to be computed in VT and */
1258 /* M left singular vectors to be computed in U */
1262 /* WORK(IL) is M by M */
1265 itau = il + ldwrkl * *m;
1269 /* (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */
1271 i__2 = *lwork - nwork + 1;
1272 sgelqf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
1275 /* Copy L to WORK(IL), zeroing out above it */
1277 slacpy_("L", m, m, &a[a_offset], lda, &work[il], &ldwrkl);
1280 slaset_("U", &i__2, &i__1, &c_b227, &c_b227, &work[il +
1283 /* Generate Q in A */
1284 /* (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */
1286 i__2 = *lwork - nwork + 1;
1287 sorglq_(m, n, m, &a[a_offset], lda, &work[itau], &work[nwork],
1294 /* Bidiagonalize L in WORK(IU), copying result to U */
1295 /* (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB) */
1297 i__2 = *lwork - nwork + 1;
1298 sgebrd_(m, m, &work[il], &ldwrkl, &s[1], &work[ie], &work[
1299 itauq], &work[itaup], &work[nwork], &i__2, &ierr);
1301 /* Perform bidiagonal SVD, computing left singular vectors */
1302 /* of bidiagonal matrix in U and computing right singular */
1303 /* vectors of bidiagonal matrix in VT */
1304 /* (Workspace: need M+BDSPAC) */
1306 sbdsdc_("U", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &vt[
1307 vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1],
1310 /* Overwrite U by left singular vectors of L and VT */
1311 /* by right singular vectors of L */
1312 /* (Workspace: need M*M+3*M, prefer M*M+2*M+M*NB) */
1314 i__2 = *lwork - nwork + 1;
1315 sormbr_("Q", "L", "N", m, m, m, &work[il], &ldwrkl, &work[
1316 itauq], &u[u_offset], ldu, &work[nwork], &i__2, &ierr);
1317 i__2 = *lwork - nwork + 1;
1318 sormbr_("P", "R", "T", m, m, m, &work[il], &ldwrkl, &work[
1319 itaup], &vt[vt_offset], ldvt, &work[nwork], &i__2, &
1322 /* Multiply right singular vectors of L in WORK(IL) by */
1323 /* Q in A, storing result in VT */
1324 /* (Workspace: need M*M) */
1326 slacpy_("F", m, m, &vt[vt_offset], ldvt, &work[il], &ldwrkl);
1327 sgemm_("N", "N", m, n, m, &c_b248, &work[il], &ldwrkl, &a[
1328 a_offset], lda, &c_b227, &vt[vt_offset], ldvt);
1332 /* Path 4t (N much larger than M, JOBZ='A') */
1333 /* N right singular vectors to be computed in VT and */
1334 /* M left singular vectors to be computed in U */
1338 /* WORK(IVT) is M by M */
1341 itau = ivt + ldwkvt * *m;
1344 /* Compute A=L*Q, copying result to VT */
1345 /* (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */
1347 i__2 = *lwork - nwork + 1;
1348 sgelqf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
1350 slacpy_("U", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt);
1352 /* Generate Q in VT */
1353 /* (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */
1355 i__2 = *lwork - nwork + 1;
1356 sorglq_(n, n, m, &vt[vt_offset], ldvt, &work[itau], &work[
1357 nwork], &i__2, &ierr);
1359 /* Produce L in A, zeroing out other entries */
1363 slaset_("U", &i__2, &i__1, &c_b227, &c_b227, &a[(a_dim1 << 1)
1370 /* Bidiagonalize L in A */
1371 /* (Workspace: need M*M+4*M, prefer M*M+3*M+2*M*NB) */
1373 i__2 = *lwork - nwork + 1;
1374 sgebrd_(m, m, &a[a_offset], lda, &s[1], &work[ie], &work[
1375 itauq], &work[itaup], &work[nwork], &i__2, &ierr);
1377 /* Perform bidiagonal SVD, computing left singular vectors */
1378 /* of bidiagonal matrix in U and computing right singular */
1379 /* vectors of bidiagonal matrix in WORK(IVT) */
1380 /* (Workspace: need M+M*M+BDSPAC) */
1382 sbdsdc_("U", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &
1383 work[ivt], &ldwkvt, dum, idum, &work[nwork], &iwork[1]
1386 /* Overwrite U by left singular vectors of L and WORK(IVT) */
1387 /* by right singular vectors of L */
1388 /* (Workspace: need M*M+3*M, prefer M*M+2*M+M*NB) */
1390 i__2 = *lwork - nwork + 1;
1391 sormbr_("Q", "L", "N", m, m, m, &a[a_offset], lda, &work[
1392 itauq], &u[u_offset], ldu, &work[nwork], &i__2, &ierr);
1393 i__2 = *lwork - nwork + 1;
1394 sormbr_("P", "R", "T", m, m, m, &a[a_offset], lda, &work[
1395 itaup], &work[ivt], &ldwkvt, &work[nwork], &i__2, &
1398 /* Multiply right singular vectors of L in WORK(IVT) by */
1399 /* Q in VT, storing result in A */
1400 /* (Workspace: need M*M) */
1402 sgemm_("N", "N", m, n, m, &c_b248, &work[ivt], &ldwkvt, &vt[
1403 vt_offset], ldvt, &c_b227, &a[a_offset], lda);
1405 /* Copy right singular vectors of A from A to VT */
1407 slacpy_("F", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt);
1415 /* Path 5t (N greater than M, but not much larger) */
1416 /* Reduce to bidiagonal form without LQ decomposition */
1423 /* Bidiagonalize A */
1424 /* (Workspace: need 3*M+N, prefer 3*M+(M+N)*NB) */
1426 i__2 = *lwork - nwork + 1;
1427 sgebrd_(m, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &
1428 work[itaup], &work[nwork], &i__2, &ierr);
1431 /* Perform bidiagonal SVD, only computing singular values */
1432 /* (Workspace: need M+BDSPAC) */
1434 sbdsdc_("L", "N", m, &s[1], &work[ie], dum, &c__1, dum, &c__1,
1435 dum, idum, &work[nwork], &iwork[1], info);
1439 if (*lwork >= *m * *n + *m * 3 + bdspac) {
1441 /* WORK( IVT ) is M by N */
1443 slaset_("F", m, n, &c_b227, &c_b227, &work[ivt], &ldwkvt);
1444 nwork = ivt + ldwkvt * *n;
1447 /* WORK( IVT ) is M by M */
1449 nwork = ivt + ldwkvt * *m;
1452 /* WORK(IL) is M by CHUNK */
1454 chunk = (*lwork - *m * *m - *m * 3) / *m;
1457 /* Perform bidiagonal SVD, computing left singular vectors */
1458 /* of bidiagonal matrix in U and computing right singular */
1459 /* vectors of bidiagonal matrix in WORK(IVT) */
1460 /* (Workspace: need M*M+BDSPAC) */
1462 sbdsdc_("L", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &
1463 work[ivt], &ldwkvt, dum, idum, &work[nwork], &iwork[1]
1466 /* Overwrite U by left singular vectors of A */
1467 /* (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */
1469 i__2 = *lwork - nwork + 1;
1470 sormbr_("Q", "L", "N", m, m, n, &a[a_offset], lda, &work[
1471 itauq], &u[u_offset], ldu, &work[nwork], &i__2, &ierr);
1473 if (*lwork >= *m * *n + *m * 3 + bdspac) {
1475 /* Overwrite WORK(IVT) by left singular vectors of A */
1476 /* (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */
1478 i__2 = *lwork - nwork + 1;
1479 sormbr_("P", "R", "T", m, n, m, &a[a_offset], lda, &work[
1480 itaup], &work[ivt], &ldwkvt, &work[nwork], &i__2,
1483 /* Copy right singular vectors of A from WORK(IVT) to A */
1485 slacpy_("F", m, n, &work[ivt], &ldwkvt, &a[a_offset], lda);
1488 /* Generate P**T in A */
1489 /* (Workspace: need M*M+2*M, prefer M*M+M+M*NB) */
1491 i__2 = *lwork - nwork + 1;
1492 sorgbr_("P", m, n, m, &a[a_offset], lda, &work[itaup], &
1493 work[nwork], &i__2, &ierr);
1495 /* Multiply Q in A by right singular vectors of */
1496 /* bidiagonal matrix in WORK(IVT), storing result in */
1497 /* WORK(IL) and copying to A */
1498 /* (Workspace: need 2*M*M, prefer M*M+M*N) */
1502 for (i__ = 1; i__1 < 0 ? i__ >= i__2 : i__ <= i__2; i__ +=
1505 i__3 = *n - i__ + 1;
1506 blk = min(i__3,chunk);
1507 sgemm_("N", "N", m, &blk, m, &c_b248, &work[ivt], &
1508 ldwkvt, &a[i__ * a_dim1 + 1], lda, &c_b227, &
1510 slacpy_("F", m, &blk, &work[il], m, &a[i__ * a_dim1 +
1517 /* Perform bidiagonal SVD, computing left singular vectors */
1518 /* of bidiagonal matrix in U and computing right singular */
1519 /* vectors of bidiagonal matrix in VT */
1520 /* (Workspace: need M+BDSPAC) */
1522 slaset_("F", m, n, &c_b227, &c_b227, &vt[vt_offset], ldvt);
1523 sbdsdc_("L", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &vt[
1524 vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1],
1527 /* Overwrite U by left singular vectors of A and VT */
1528 /* by right singular vectors of A */
1529 /* (Workspace: need 3*M, prefer 2*M+M*NB) */
1531 i__1 = *lwork - nwork + 1;
1532 sormbr_("Q", "L", "N", m, m, n, &a[a_offset], lda, &work[
1533 itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
1534 i__1 = *lwork - nwork + 1;
1535 sormbr_("P", "R", "T", m, n, m, &a[a_offset], lda, &work[
1536 itaup], &vt[vt_offset], ldvt, &work[nwork], &i__1, &
1540 /* Perform bidiagonal SVD, computing left singular vectors */
1541 /* of bidiagonal matrix in U and computing right singular */
1542 /* vectors of bidiagonal matrix in VT */
1543 /* (Workspace: need M+BDSPAC) */
1545 slaset_("F", n, n, &c_b227, &c_b227, &vt[vt_offset], ldvt);
1546 sbdsdc_("L", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &vt[
1547 vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1],
1550 /* Set the right corner of VT to identity matrix */
1555 slaset_("F", &i__1, &i__2, &c_b227, &c_b248, &vt[*m + 1 +
1556 (*m + 1) * vt_dim1], ldvt);
1559 /* Overwrite U by left singular vectors of A and VT */
1560 /* by right singular vectors of A */
1561 /* (Workspace: need 2*M+N, prefer 2*M+N*NB) */
1563 i__1 = *lwork - nwork + 1;
1564 sormbr_("Q", "L", "N", m, m, n, &a[a_offset], lda, &work[
1565 itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
1566 i__1 = *lwork - nwork + 1;
1567 sormbr_("P", "R", "T", n, n, m, &a[a_offset], lda, &work[
1568 itaup], &vt[vt_offset], ldvt, &work[nwork], &i__1, &
1576 /* Undo scaling if necessary */
1579 if (anrm > bignum) {
1580 slascl_("G", &c__0, &c__0, &bignum, &anrm, &minmn, &c__1, &s[1], &
1583 if (anrm < smlnum) {
1584 slascl_("G", &c__0, &c__0, &smlnum, &anrm, &minmn, &c__1, &s[1], &
1589 /* Return optimal workspace in WORK(1) */
1591 work[1] = (real) maxwrk;