C_LAPACK: Fixes to make it compile with MSVC (#3605)
[platform/upstream/openblas.git] / lapack-netlib / SRC / dgesdd.c
1 #include <math.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <stdio.h>
5 #include <complex.h>
6 #ifdef complex
7 #undef complex
8 #endif
9 #ifdef I
10 #undef I
11 #endif
12
13 #if defined(_WIN64)
14 typedef long long BLASLONG;
15 typedef unsigned long long BLASULONG;
16 #else
17 typedef long BLASLONG;
18 typedef unsigned long BLASULONG;
19 #endif
20
21 #ifdef LAPACK_ILP64
22 typedef BLASLONG blasint;
23 #if defined(_WIN64)
24 #define blasabs(x) llabs(x)
25 #else
26 #define blasabs(x) labs(x)
27 #endif
28 #else
29 typedef int blasint;
30 #define blasabs(x) abs(x)
31 #endif
32
33 typedef blasint integer;
34
35 typedef unsigned int uinteger;
36 typedef char *address;
37 typedef short int shortint;
38 typedef float real;
39 typedef double doublereal;
40 typedef struct { real r, i; } complex;
41 typedef struct { doublereal r, i; } doublecomplex;
42 #ifdef _MSC_VER
43 static inline _Fcomplex Cf(complex *z) {_Fcomplex zz={z->r , z->i}; return zz;}
44 static inline _Dcomplex Cd(doublecomplex *z) {_Dcomplex zz={z->r , z->i};return zz;}
45 static inline _Fcomplex * _pCf(complex *z) {return (_Fcomplex*)z;}
46 static inline _Dcomplex * _pCd(doublecomplex *z) {return (_Dcomplex*)z;}
47 #else
48 static inline _Complex float Cf(complex *z) {return z->r + z->i*_Complex_I;}
49 static inline _Complex double Cd(doublecomplex *z) {return z->r + z->i*_Complex_I;}
50 static inline _Complex float * _pCf(complex *z) {return (_Complex float*)z;}
51 static inline _Complex double * _pCd(doublecomplex *z) {return (_Complex double*)z;}
52 #endif
53 #define pCf(z) (*_pCf(z))
54 #define pCd(z) (*_pCd(z))
55 typedef int logical;
56 typedef short int shortlogical;
57 typedef char logical1;
58 typedef char integer1;
59
60 #define TRUE_ (1)
61 #define FALSE_ (0)
62
63 /* Extern is for use with -E */
64 #ifndef Extern
65 #define Extern extern
66 #endif
67
68 /* I/O stuff */
69
70 typedef int flag;
71 typedef int ftnlen;
72 typedef int ftnint;
73
74 /*external read, write*/
75 typedef struct
76 {       flag cierr;
77         ftnint ciunit;
78         flag ciend;
79         char *cifmt;
80         ftnint cirec;
81 } cilist;
82
83 /*internal read, write*/
84 typedef struct
85 {       flag icierr;
86         char *iciunit;
87         flag iciend;
88         char *icifmt;
89         ftnint icirlen;
90         ftnint icirnum;
91 } icilist;
92
93 /*open*/
94 typedef struct
95 {       flag oerr;
96         ftnint ounit;
97         char *ofnm;
98         ftnlen ofnmlen;
99         char *osta;
100         char *oacc;
101         char *ofm;
102         ftnint orl;
103         char *oblnk;
104 } olist;
105
106 /*close*/
107 typedef struct
108 {       flag cerr;
109         ftnint cunit;
110         char *csta;
111 } cllist;
112
113 /*rewind, backspace, endfile*/
114 typedef struct
115 {       flag aerr;
116         ftnint aunit;
117 } alist;
118
119 /* inquire */
120 typedef struct
121 {       flag inerr;
122         ftnint inunit;
123         char *infile;
124         ftnlen infilen;
125         ftnint  *inex;  /*parameters in standard's order*/
126         ftnint  *inopen;
127         ftnint  *innum;
128         ftnint  *innamed;
129         char    *inname;
130         ftnlen  innamlen;
131         char    *inacc;
132         ftnlen  inacclen;
133         char    *inseq;
134         ftnlen  inseqlen;
135         char    *indir;
136         ftnlen  indirlen;
137         char    *infmt;
138         ftnlen  infmtlen;
139         char    *inform;
140         ftnint  informlen;
141         char    *inunf;
142         ftnlen  inunflen;
143         ftnint  *inrecl;
144         ftnint  *innrec;
145         char    *inblank;
146         ftnlen  inblanklen;
147 } inlist;
148
149 #define VOID void
150
151 union Multitype {       /* for multiple entry points */
152         integer1 g;
153         shortint h;
154         integer i;
155         /* longint j; */
156         real r;
157         doublereal d;
158         complex c;
159         doublecomplex z;
160         };
161
162 typedef union Multitype Multitype;
163
164 struct Vardesc {        /* for Namelist */
165         char *name;
166         char *addr;
167         ftnlen *dims;
168         int  type;
169         };
170 typedef struct Vardesc Vardesc;
171
172 struct Namelist {
173         char *name;
174         Vardesc **vars;
175         int nvars;
176         };
177 typedef struct Namelist Namelist;
178
179 #define abs(x) ((x) >= 0 ? (x) : -(x))
180 #define dabs(x) (fabs(x))
181 #define f2cmin(a,b) ((a) <= (b) ? (a) : (b))
182 #define f2cmax(a,b) ((a) >= (b) ? (a) : (b))
183 #define dmin(a,b) (f2cmin(a,b))
184 #define dmax(a,b) (f2cmax(a,b))
185 #define bit_test(a,b)   ((a) >> (b) & 1)
186 #define bit_clear(a,b)  ((a) & ~((uinteger)1 << (b)))
187 #define bit_set(a,b)    ((a) |  ((uinteger)1 << (b)))
188
189 #define abort_() { sig_die("Fortran abort routine called", 1); }
190 #define c_abs(z) (cabsf(Cf(z)))
191 #define c_cos(R,Z) { pCf(R)=ccos(Cf(Z)); }
192 #ifdef _MSC_VER
193 #define c_div(c, a, b) {Cf(c)._Val[0] = (Cf(a)._Val[0]/Cf(b)._Val[0]); Cf(c)._Val[1]=(Cf(a)._Val[1]/Cf(b)._Val[1]);}
194 #define z_div(c, a, b) {Cd(c)._Val[0] = (Cd(a)._Val[0]/Cd(b)._Val[0]); Cd(c)._Val[1]=(Cd(a)._Val[1]/df(b)._Val[1]);}
195 #else
196 #define c_div(c, a, b) {pCf(c) = Cf(a)/Cf(b);}
197 #define z_div(c, a, b) {pCd(c) = Cd(a)/Cd(b);}
198 #endif
199 #define c_exp(R, Z) {pCf(R) = cexpf(Cf(Z));}
200 #define c_log(R, Z) {pCf(R) = clogf(Cf(Z));}
201 #define c_sin(R, Z) {pCf(R) = csinf(Cf(Z));}
202 //#define c_sqrt(R, Z) {*(R) = csqrtf(Cf(Z));}
203 #define c_sqrt(R, Z) {pCf(R) = csqrtf(Cf(Z));}
204 #define d_abs(x) (fabs(*(x)))
205 #define d_acos(x) (acos(*(x)))
206 #define d_asin(x) (asin(*(x)))
207 #define d_atan(x) (atan(*(x)))
208 #define d_atn2(x, y) (atan2(*(x),*(y)))
209 #define d_cnjg(R, Z) { pCd(R) = conj(Cd(Z)); }
210 #define r_cnjg(R, Z) { pCf(R) = conjf(Cf(Z)); }
211 #define d_cos(x) (cos(*(x)))
212 #define d_cosh(x) (cosh(*(x)))
213 #define d_dim(__a, __b) ( *(__a) > *(__b) ? *(__a) - *(__b) : 0.0 )
214 #define d_exp(x) (exp(*(x)))
215 #define d_imag(z) (cimag(Cd(z)))
216 #define r_imag(z) (cimagf(Cf(z)))
217 #define d_int(__x) (*(__x)>0 ? floor(*(__x)) : -floor(- *(__x)))
218 #define r_int(__x) (*(__x)>0 ? floor(*(__x)) : -floor(- *(__x)))
219 #define d_lg10(x) ( 0.43429448190325182765 * log(*(x)) )
220 #define r_lg10(x) ( 0.43429448190325182765 * log(*(x)) )
221 #define d_log(x) (log(*(x)))
222 #define d_mod(x, y) (fmod(*(x), *(y)))
223 #define u_nint(__x) ((__x)>=0 ? floor((__x) + .5) : -floor(.5 - (__x)))
224 #define d_nint(x) u_nint(*(x))
225 #define u_sign(__a,__b) ((__b) >= 0 ? ((__a) >= 0 ? (__a) : -(__a)) : -((__a) >= 0 ? (__a) : -(__a)))
226 #define d_sign(a,b) u_sign(*(a),*(b))
227 #define r_sign(a,b) u_sign(*(a),*(b))
228 #define d_sin(x) (sin(*(x)))
229 #define d_sinh(x) (sinh(*(x)))
230 #define d_sqrt(x) (sqrt(*(x)))
231 #define d_tan(x) (tan(*(x)))
232 #define d_tanh(x) (tanh(*(x)))
233 #define i_abs(x) abs(*(x))
234 #define i_dnnt(x) ((integer)u_nint(*(x)))
235 #define i_len(s, n) (n)
236 #define i_nint(x) ((integer)u_nint(*(x)))
237 #define i_sign(a,b) ((integer)u_sign((integer)*(a),(integer)*(b)))
238 #define pow_dd(ap, bp) ( pow(*(ap), *(bp)))
239 #define pow_si(B,E) spow_ui(*(B),*(E))
240 #define pow_ri(B,E) spow_ui(*(B),*(E))
241 #define pow_di(B,E) dpow_ui(*(B),*(E))
242 #define pow_zi(p, a, b) {pCd(p) = zpow_ui(Cd(a), *(b));}
243 #define pow_ci(p, a, b) {pCf(p) = cpow_ui(Cf(a), *(b));}
244 #define pow_zz(R,A,B) {pCd(R) = cpow(Cd(A),*(B));}
245 #define s_cat(lpp, rpp, rnp, np, llp) {         ftnlen i, nc, ll; char *f__rp, *lp;     ll = (llp); lp = (lpp);         for(i=0; i < (int)*(np); ++i) {                 nc = ll;                if((rnp)[i] < nc) nc = (rnp)[i];                ll -= nc;               f__rp = (rpp)[i];               while(--nc >= 0) *lp++ = *(f__rp)++;         }  while(--ll >= 0) *lp++ = ' '; }
246 #define s_cmp(a,b,c,d) ((integer)strncmp((a),(b),f2cmin((c),(d))))
247 #define s_copy(A,B,C,D) { int __i,__m; for (__i=0, __m=f2cmin((C),(D)); __i<__m && (B)[__i] != 0; ++__i) (A)[__i] = (B)[__i]; }
248 #define sig_die(s, kill) { exit(1); }
249 #define s_stop(s, n) {exit(0);}
250 static char junk[] = "\n@(#)LIBF77 VERSION 19990503\n";
251 #define z_abs(z) (cabs(Cd(z)))
252 #define z_exp(R, Z) {pCd(R) = cexp(Cd(Z));}
253 #define z_sqrt(R, Z) {pCd(R) = csqrt(Cd(Z));}
254 #define myexit_() break;
255 #define mycycle() continue;
256 #define myceiling(w) {ceil(w)}
257 #define myhuge(w) {HUGE_VAL}
258 //#define mymaxloc_(w,s,e,n) {if (sizeof(*(w)) == sizeof(double)) dmaxloc_((w),*(s),*(e),n); else dmaxloc_((w),*(s),*(e),n);}
259 #define mymaxloc(w,s,e,n) {dmaxloc_(w,*(s),*(e),n)}
260
261 /* procedure parameter types for -A and -C++ */
262
263 #define F2C_proc_par_types 1
264 #ifdef __cplusplus
265 typedef logical (*L_fp)(...);
266 #else
267 typedef logical (*L_fp)();
268 #endif
269
270 static float spow_ui(float x, integer n) {
271         float pow=1.0; unsigned long int u;
272         if(n != 0) {
273                 if(n < 0) n = -n, x = 1/x;
274                 for(u = n; ; ) {
275                         if(u & 01) pow *= x;
276                         if(u >>= 1) x *= x;
277                         else break;
278                 }
279         }
280         return pow;
281 }
282 static double dpow_ui(double x, integer n) {
283         double pow=1.0; unsigned long int u;
284         if(n != 0) {
285                 if(n < 0) n = -n, x = 1/x;
286                 for(u = n; ; ) {
287                         if(u & 01) pow *= x;
288                         if(u >>= 1) x *= x;
289                         else break;
290                 }
291         }
292         return pow;
293 }
294 #ifdef _MSC_VER
295 static _Fcomplex cpow_ui(complex x, integer n) {
296         complex pow={1.0,0.0}; unsigned long int u;
297                 if(n != 0) {
298                 if(n < 0) n = -n, x.r = 1/x.r, x.i=1/x.i;
299                 for(u = n; ; ) {
300                         if(u & 01) pow.r *= x.r, pow.i *= x.i;
301                         if(u >>= 1) x.r *= x.r, x.i *= x.i;
302                         else break;
303                 }
304         }
305         _Fcomplex p={pow.r, pow.i};
306         return p;
307 }
308 #else
309 static _Complex float cpow_ui(_Complex float x, integer n) {
310         _Complex float pow=1.0; unsigned long int u;
311         if(n != 0) {
312                 if(n < 0) n = -n, x = 1/x;
313                 for(u = n; ; ) {
314                         if(u & 01) pow *= x;
315                         if(u >>= 1) x *= x;
316                         else break;
317                 }
318         }
319         return pow;
320 }
321 #endif
322 #ifdef _MSC_VER
323 static _Dcomplex zpow_ui(_Dcomplex x, integer n) {
324         _Dcomplex pow={1.0,0.0}; unsigned long int u;
325         if(n != 0) {
326                 if(n < 0) n = -n, x._Val[0] = 1/x._Val[0], x._Val[1] =1/x._Val[1];
327                 for(u = n; ; ) {
328                         if(u & 01) pow._Val[0] *= x._Val[0], pow._Val[1] *= x._Val[1];
329                         if(u >>= 1) x._Val[0] *= x._Val[0], x._Val[1] *= x._Val[1];
330                         else break;
331                 }
332         }
333         _Dcomplex p = {pow._Val[0], pow._Val[1]};
334         return p;
335 }
336 #else
337 static _Complex double zpow_ui(_Complex double x, integer n) {
338         _Complex double pow=1.0; unsigned long int u;
339         if(n != 0) {
340                 if(n < 0) n = -n, x = 1/x;
341                 for(u = n; ; ) {
342                         if(u & 01) pow *= x;
343                         if(u >>= 1) x *= x;
344                         else break;
345                 }
346         }
347         return pow;
348 }
349 #endif
350 static integer pow_ii(integer x, integer n) {
351         integer pow; unsigned long int u;
352         if (n <= 0) {
353                 if (n == 0 || x == 1) pow = 1;
354                 else if (x != -1) pow = x == 0 ? 1/x : 0;
355                 else n = -n;
356         }
357         if ((n > 0) || !(n == 0 || x == 1 || x != -1)) {
358                 u = n;
359                 for(pow = 1; ; ) {
360                         if(u & 01) pow *= x;
361                         if(u >>= 1) x *= x;
362                         else break;
363                 }
364         }
365         return pow;
366 }
367 static integer dmaxloc_(double *w, integer s, integer e, integer *n)
368 {
369         double m; integer i, mi;
370         for(m=w[s-1], mi=s, i=s+1; i<=e; i++)
371                 if (w[i-1]>m) mi=i ,m=w[i-1];
372         return mi-s+1;
373 }
374 static integer smaxloc_(float *w, integer s, integer e, integer *n)
375 {
376         float m; integer i, mi;
377         for(m=w[s-1], mi=s, i=s+1; i<=e; i++)
378                 if (w[i-1]>m) mi=i ,m=w[i-1];
379         return mi-s+1;
380 }
381 static inline void cdotc_(complex *z, integer *n_, complex *x, integer *incx_, complex *y, integer *incy_) {
382         integer n = *n_, incx = *incx_, incy = *incy_, i;
383 #ifdef _MSC_VER
384         _Fcomplex zdotc = {0.0, 0.0};
385         if (incx == 1 && incy == 1) {
386                 for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */
387                         zdotc._Val[0] += conjf(Cf(&x[i]))._Val[0] * Cf(&y[i])._Val[0];
388                         zdotc._Val[1] += conjf(Cf(&x[i]))._Val[1] * Cf(&y[i])._Val[1];
389                 }
390         } else {
391                 for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */
392                         zdotc._Val[0] += conjf(Cf(&x[i*incx]))._Val[0] * Cf(&y[i*incy])._Val[0];
393                         zdotc._Val[1] += conjf(Cf(&x[i*incx]))._Val[1] * Cf(&y[i*incy])._Val[1];
394                 }
395         }
396         pCf(z) = zdotc;
397 }
398 #else
399         _Complex float zdotc = 0.0;
400         if (incx == 1 && incy == 1) {
401                 for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */
402                         zdotc += conjf(Cf(&x[i])) * Cf(&y[i]);
403                 }
404         } else {
405                 for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */
406                         zdotc += conjf(Cf(&x[i*incx])) * Cf(&y[i*incy]);
407                 }
408         }
409         pCf(z) = zdotc;
410 }
411 #endif
412 static inline void zdotc_(doublecomplex *z, integer *n_, doublecomplex *x, integer *incx_, doublecomplex *y, integer *incy_) {
413         integer n = *n_, incx = *incx_, incy = *incy_, i;
414 #ifdef _MSC_VER
415         _Dcomplex zdotc = {0.0, 0.0};
416         if (incx == 1 && incy == 1) {
417                 for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */
418                         zdotc._Val[0] += conj(Cd(&x[i]))._Val[0] * Cd(&y[i])._Val[0];
419                         zdotc._Val[1] += conj(Cd(&x[i]))._Val[1] * Cd(&y[i])._Val[1];
420                 }
421         } else {
422                 for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */
423                         zdotc._Val[0] += conj(Cd(&x[i*incx]))._Val[0] * Cd(&y[i*incy])._Val[0];
424                         zdotc._Val[1] += conj(Cd(&x[i*incx]))._Val[1] * Cd(&y[i*incy])._Val[1];
425                 }
426         }
427         pCd(z) = zdotc;
428 }
429 #else
430         _Complex double zdotc = 0.0;
431         if (incx == 1 && incy == 1) {
432                 for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */
433                         zdotc += conj(Cd(&x[i])) * Cd(&y[i]);
434                 }
435         } else {
436                 for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */
437                         zdotc += conj(Cd(&x[i*incx])) * Cd(&y[i*incy]);
438                 }
439         }
440         pCd(z) = zdotc;
441 }
442 #endif  
443 static inline void cdotu_(complex *z, integer *n_, complex *x, integer *incx_, complex *y, integer *incy_) {
444         integer n = *n_, incx = *incx_, incy = *incy_, i;
445 #ifdef _MSC_VER
446         _Fcomplex zdotc = {0.0, 0.0};
447         if (incx == 1 && incy == 1) {
448                 for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */
449                         zdotc._Val[0] += Cf(&x[i])._Val[0] * Cf(&y[i])._Val[0];
450                         zdotc._Val[1] += Cf(&x[i])._Val[1] * Cf(&y[i])._Val[1];
451                 }
452         } else {
453                 for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */
454                         zdotc._Val[0] += Cf(&x[i*incx])._Val[0] * Cf(&y[i*incy])._Val[0];
455                         zdotc._Val[1] += Cf(&x[i*incx])._Val[1] * Cf(&y[i*incy])._Val[1];
456                 }
457         }
458         pCf(z) = zdotc;
459 }
460 #else
461         _Complex float zdotc = 0.0;
462         if (incx == 1 && incy == 1) {
463                 for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */
464                         zdotc += Cf(&x[i]) * Cf(&y[i]);
465                 }
466         } else {
467                 for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */
468                         zdotc += Cf(&x[i*incx]) * Cf(&y[i*incy]);
469                 }
470         }
471         pCf(z) = zdotc;
472 }
473 #endif
474 static inline void zdotu_(doublecomplex *z, integer *n_, doublecomplex *x, integer *incx_, doublecomplex *y, integer *incy_) {
475         integer n = *n_, incx = *incx_, incy = *incy_, i;
476 #ifdef _MSC_VER
477         _Dcomplex zdotc = {0.0, 0.0};
478         if (incx == 1 && incy == 1) {
479                 for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */
480                         zdotc._Val[0] += Cd(&x[i])._Val[0] * Cd(&y[i])._Val[0];
481                         zdotc._Val[1] += Cd(&x[i])._Val[1] * Cd(&y[i])._Val[1];
482                 }
483         } else {
484                 for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */
485                         zdotc._Val[0] += Cd(&x[i*incx])._Val[0] * Cd(&y[i*incy])._Val[0];
486                         zdotc._Val[1] += Cd(&x[i*incx])._Val[1] * Cd(&y[i*incy])._Val[1];
487                 }
488         }
489         pCd(z) = zdotc;
490 }
491 #else
492         _Complex double zdotc = 0.0;
493         if (incx == 1 && incy == 1) {
494                 for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */
495                         zdotc += Cd(&x[i]) * Cd(&y[i]);
496                 }
497         } else {
498                 for (i=0;i<n;i++) { /* zdotc = zdotc + dconjg(x(i))* y(i) */
499                         zdotc += Cd(&x[i*incx]) * Cd(&y[i*incy]);
500                 }
501         }
502         pCd(z) = zdotc;
503 }
504 #endif
505 /*  -- translated by f2c (version 20000121).
506    You must link the resulting object file with the libraries:
507         -lf2c -lm   (in that order)
508 */
509
510
511
512
513 /* Table of constant values */
514
515 static integer c_n1 = -1;
516 static integer c__0 = 0;
517 static doublereal c_b63 = 0.;
518 static integer c__1 = 1;
519 static doublereal c_b84 = 1.;
520
521 /* > \brief \b DGESDD */
522
523 /*  =========== DOCUMENTATION =========== */
524
525 /* Online html documentation available at */
526 /*            http://www.netlib.org/lapack/explore-html/ */
527
528 /* > \htmlonly */
529 /* > Download DGESDD + dependencies */
530 /* > <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/dgesdd.
531 f"> */
532 /* > [TGZ]</a> */
533 /* > <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/dgesdd.
534 f"> */
535 /* > [ZIP]</a> */
536 /* > <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/dgesdd.
537 f"> */
538 /* > [TXT]</a> */
539 /* > \endhtmlonly */
540
541 /*  Definition: */
542 /*  =========== */
543
544 /*       SUBROUTINE DGESDD( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT, */
545 /*                          WORK, LWORK, IWORK, INFO ) */
546
547 /*       CHARACTER          JOBZ */
548 /*       INTEGER            INFO, LDA, LDU, LDVT, LWORK, M, N */
549 /*       INTEGER            IWORK( * ) */
550 /*       DOUBLE PRECISION   A( LDA, * ), S( * ), U( LDU, * ), */
551 /*      $                   VT( LDVT, * ), WORK( * ) */
552
553
554 /* > \par Purpose: */
555 /*  ============= */
556 /* > */
557 /* > \verbatim */
558 /* > */
559 /* > DGESDD computes the singular value decomposition (SVD) of a real */
560 /* > M-by-N matrix A, optionally computing the left and right singular */
561 /* > vectors.  If singular vectors are desired, it uses a */
562 /* > divide-and-conquer algorithm. */
563 /* > */
564 /* > The SVD is written */
565 /* > */
566 /* >      A = U * SIGMA * transpose(V) */
567 /* > */
568 /* > where SIGMA is an M-by-N matrix which is zero except for its */
569 /* > f2cmin(m,n) diagonal elements, U is an M-by-M orthogonal matrix, and */
570 /* > V is an N-by-N orthogonal matrix.  The diagonal elements of SIGMA */
571 /* > are the singular values of A; they are real and non-negative, and */
572 /* > are returned in descending order.  The first f2cmin(m,n) columns of */
573 /* > U and V are the left and right singular vectors of A. */
574 /* > */
575 /* > Note that the routine returns VT = V**T, not V. */
576 /* > */
577 /* > The divide and conquer algorithm makes very mild assumptions about */
578 /* > floating point arithmetic. It will work on machines with a guard */
579 /* > digit in add/subtract, or on those binary machines without guard */
580 /* > digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or */
581 /* > Cray-2. It could conceivably fail on hexadecimal or decimal machines */
582 /* > without guard digits, but we know of none. */
583 /* > \endverbatim */
584
585 /*  Arguments: */
586 /*  ========== */
587
588 /* > \param[in] JOBZ */
589 /* > \verbatim */
590 /* >          JOBZ is CHARACTER*1 */
591 /* >          Specifies options for computing all or part of the matrix U: */
592 /* >          = 'A':  all M columns of U and all N rows of V**T are */
593 /* >                  returned in the arrays U and VT; */
594 /* >          = 'S':  the first f2cmin(M,N) columns of U and the first */
595 /* >                  f2cmin(M,N) rows of V**T are returned in the arrays U */
596 /* >                  and VT; */
597 /* >          = 'O':  If M >= N, the first N columns of U are overwritten */
598 /* >                  on the array A and all rows of V**T are returned in */
599 /* >                  the array VT; */
600 /* >                  otherwise, all columns of U are returned in the */
601 /* >                  array U and the first M rows of V**T are overwritten */
602 /* >                  in the array A; */
603 /* >          = 'N':  no columns of U or rows of V**T are computed. */
604 /* > \endverbatim */
605 /* > */
606 /* > \param[in] M */
607 /* > \verbatim */
608 /* >          M is INTEGER */
609 /* >          The number of rows of the input matrix A.  M >= 0. */
610 /* > \endverbatim */
611 /* > */
612 /* > \param[in] N */
613 /* > \verbatim */
614 /* >          N is INTEGER */
615 /* >          The number of columns of the input matrix A.  N >= 0. */
616 /* > \endverbatim */
617 /* > */
618 /* > \param[in,out] A */
619 /* > \verbatim */
620 /* >          A is DOUBLE PRECISION array, dimension (LDA,N) */
621 /* >          On entry, the M-by-N matrix A. */
622 /* >          On exit, */
623 /* >          if JOBZ = 'O',  A is overwritten with the first N columns */
624 /* >                          of U (the left singular vectors, stored */
625 /* >                          columnwise) if M >= N; */
626 /* >                          A is overwritten with the first M rows */
627 /* >                          of V**T (the right singular vectors, stored */
628 /* >                          rowwise) otherwise. */
629 /* >          if JOBZ .ne. 'O', the contents of A are destroyed. */
630 /* > \endverbatim */
631 /* > */
632 /* > \param[in] LDA */
633 /* > \verbatim */
634 /* >          LDA is INTEGER */
635 /* >          The leading dimension of the array A.  LDA >= f2cmax(1,M). */
636 /* > \endverbatim */
637 /* > */
638 /* > \param[out] S */
639 /* > \verbatim */
640 /* >          S is DOUBLE PRECISION array, dimension (f2cmin(M,N)) */
641 /* >          The singular values of A, sorted so that S(i) >= S(i+1). */
642 /* > \endverbatim */
643 /* > */
644 /* > \param[out] U */
645 /* > \verbatim */
646 /* >          U is DOUBLE PRECISION array, dimension (LDU,UCOL) */
647 /* >          UCOL = M if JOBZ = 'A' or JOBZ = 'O' and M < N; */
648 /* >          UCOL = f2cmin(M,N) if JOBZ = 'S'. */
649 /* >          If JOBZ = 'A' or JOBZ = 'O' and M < N, U contains the M-by-M */
650 /* >          orthogonal matrix U; */
651 /* >          if JOBZ = 'S', U contains the first f2cmin(M,N) columns of U */
652 /* >          (the left singular vectors, stored columnwise); */
653 /* >          if JOBZ = 'O' and M >= N, or JOBZ = 'N', U is not referenced. */
654 /* > \endverbatim */
655 /* > */
656 /* > \param[in] LDU */
657 /* > \verbatim */
658 /* >          LDU is INTEGER */
659 /* >          The leading dimension of the array U.  LDU >= 1; if */
660 /* >          JOBZ = 'S' or 'A' or JOBZ = 'O' and M < N, LDU >= M. */
661 /* > \endverbatim */
662 /* > */
663 /* > \param[out] VT */
664 /* > \verbatim */
665 /* >          VT is DOUBLE PRECISION array, dimension (LDVT,N) */
666 /* >          If JOBZ = 'A' or JOBZ = 'O' and M >= N, VT contains the */
667 /* >          N-by-N orthogonal matrix V**T; */
668 /* >          if JOBZ = 'S', VT contains the first f2cmin(M,N) rows of */
669 /* >          V**T (the right singular vectors, stored rowwise); */
670 /* >          if JOBZ = 'O' and M < N, or JOBZ = 'N', VT is not referenced. */
671 /* > \endverbatim */
672 /* > */
673 /* > \param[in] LDVT */
674 /* > \verbatim */
675 /* >          LDVT is INTEGER */
676 /* >          The leading dimension of the array VT.  LDVT >= 1; */
677 /* >          if JOBZ = 'A' or JOBZ = 'O' and M >= N, LDVT >= N; */
678 /* >          if JOBZ = 'S', LDVT >= f2cmin(M,N). */
679 /* > \endverbatim */
680 /* > */
681 /* > \param[out] WORK */
682 /* > \verbatim */
683 /* >          WORK is DOUBLE PRECISION array, dimension (MAX(1,LWORK)) */
684 /* >          On exit, if INFO = 0, WORK(1) returns the optimal LWORK; */
685 /* > \endverbatim */
686 /* > */
687 /* > \param[in] LWORK */
688 /* > \verbatim */
689 /* >          LWORK is INTEGER */
690 /* >          The dimension of the array WORK. LWORK >= 1. */
691 /* >          If LWORK = -1, a workspace query is assumed.  The optimal */
692 /* >          size for the WORK array is calculated and stored in WORK(1), */
693 /* >          and no other work except argument checking is performed. */
694 /* > */
695 /* >          Let mx = f2cmax(M,N) and mn = f2cmin(M,N). */
696 /* >          If JOBZ = 'N', LWORK >= 3*mn + f2cmax( mx, 7*mn ). */
697 /* >          If JOBZ = 'O', LWORK >= 3*mn + f2cmax( mx, 5*mn*mn + 4*mn ). */
698 /* >          If JOBZ = 'S', LWORK >= 4*mn*mn + 7*mn. */
699 /* >          If JOBZ = 'A', LWORK >= 4*mn*mn + 6*mn + mx. */
700 /* >          These are not tight minimums in all cases; see comments inside code. */
701 /* >          For good performance, LWORK should generally be larger; */
702 /* >          a query is recommended. */
703 /* > \endverbatim */
704 /* > */
705 /* > \param[out] IWORK */
706 /* > \verbatim */
707 /* >          IWORK is INTEGER array, dimension (8*f2cmin(M,N)) */
708 /* > \endverbatim */
709 /* > */
710 /* > \param[out] INFO */
711 /* > \verbatim */
712 /* >          INFO is INTEGER */
713 /* >          = 0:  successful exit. */
714 /* >          < 0:  if INFO = -i, the i-th argument had an illegal value. */
715 /* >          > 0:  DBDSDC did not converge, updating process failed. */
716 /* > \endverbatim */
717
718 /*  Authors: */
719 /*  ======== */
720
721 /* > \author Univ. of Tennessee */
722 /* > \author Univ. of California Berkeley */
723 /* > \author Univ. of Colorado Denver */
724 /* > \author NAG Ltd. */
725
726 /* > \date June 2016 */
727
728 /* > \ingroup doubleGEsing */
729
730 /* > \par Contributors: */
731 /*  ================== */
732 /* > */
733 /* >     Ming Gu and Huan Ren, Computer Science Division, University of */
734 /* >     California at Berkeley, USA */
735 /* > */
736 /*  ===================================================================== */
737 /* Subroutine */ int dgesdd_(char *jobz, integer *m, integer *n, doublereal *
738         a, integer *lda, doublereal *s, doublereal *u, integer *ldu, 
739         doublereal *vt, integer *ldvt, doublereal *work, integer *lwork, 
740         integer *iwork, integer *info)
741 {
742     /* System generated locals */
743     integer a_dim1, a_offset, u_dim1, u_offset, vt_dim1, vt_offset, i__1, 
744             i__2, i__3;
745
746     /* Local variables */
747     integer lwork_dorglq_mn__, lwork_dorglq_nn__, lwork_dorgqr_mm__, 
748             lwork_dorgqr_mn__, iscl;
749     doublereal anrm;
750     integer idum[1], ierr, itau, lwork_dormbr_qln_mm__, lwork_dormbr_qln_mn__,
751              lwork_dormbr_qln_nn__, lwork_dormbr_prt_mm__, 
752             lwork_dormbr_prt_mn__, lwork_dormbr_prt_nn__, i__;
753     extern /* Subroutine */ int dgemm_(char *, char *, integer *, integer *, 
754             integer *, doublereal *, doublereal *, integer *, doublereal *, 
755             integer *, doublereal *, doublereal *, integer *);
756     extern logical lsame_(char *, char *);
757     integer chunk, minmn, wrkbl, itaup, itauq, mnthr;
758     logical wntqa;
759     integer nwork;
760     logical wntqn, wntqo, wntqs;
761     integer ie, lwork_dorgbr_p_mm__;
762     extern /* Subroutine */ int dbdsdc_(char *, char *, integer *, doublereal 
763             *, doublereal *, doublereal *, integer *, doublereal *, integer *,
764              doublereal *, integer *, doublereal *, integer *, integer *);
765     integer il, lwork_dorgbr_q_nn__;
766     extern /* Subroutine */ int dgebrd_(integer *, integer *, doublereal *, 
767             integer *, doublereal *, doublereal *, doublereal *, doublereal *,
768              doublereal *, integer *, integer *);
769     extern doublereal dlamch_(char *);
770     integer ir, bdspac;
771     extern doublereal dlange_(char *, integer *, integer *, doublereal *, 
772             integer *, doublereal *);
773     integer iu;
774     extern /* Subroutine */ int dgelqf_(integer *, integer *, doublereal *, 
775             integer *, doublereal *, doublereal *, integer *, integer *), 
776             dlascl_(char *, integer *, integer *, doublereal *, doublereal *, 
777             integer *, integer *, doublereal *, integer *, integer *),
778              dgeqrf_(integer *, integer *, doublereal *, integer *, 
779             doublereal *, doublereal *, integer *, integer *), dlacpy_(char *,
780              integer *, integer *, doublereal *, integer *, doublereal *, 
781             integer *), dlaset_(char *, integer *, integer *, 
782             doublereal *, doublereal *, doublereal *, integer *), 
783             xerbla_(char *, integer *, ftnlen), dorgbr_(char *, integer *, 
784             integer *, integer *, doublereal *, integer *, doublereal *, 
785             doublereal *, integer *, integer *);
786     extern logical disnan_(doublereal *);
787     doublereal bignum;
788     extern /* Subroutine */ int dormbr_(char *, char *, char *, integer *, 
789             integer *, integer *, doublereal *, integer *, doublereal *, 
790             doublereal *, integer *, doublereal *, integer *, integer *), dorglq_(integer *, integer *, integer *, 
791             doublereal *, integer *, doublereal *, doublereal *, integer *, 
792             integer *), dorgqr_(integer *, integer *, integer *, doublereal *,
793              integer *, doublereal *, doublereal *, integer *, integer *);
794     integer ldwrkl, ldwrkr, minwrk, ldwrku, maxwrk, ldwkvt;
795     doublereal smlnum;
796     logical wntqas, lquery;
797     integer blk;
798     doublereal dum[1], eps;
799     integer ivt, lwork_dgebrd_mm__, lwork_dgebrd_mn__, lwork_dgebrd_nn__, 
800             lwork_dgelqf_mn__, lwork_dgeqrf_mn__;
801
802
803 /*  -- LAPACK driver routine (version 3.7.0) -- */
804 /*  -- LAPACK is a software package provided by Univ. of Tennessee,    -- */
805 /*  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..-- */
806 /*     June 2016 */
807
808
809 /*  ===================================================================== */
810
811
812 /*     Test the input arguments */
813
814     /* Parameter adjustments */
815     a_dim1 = *lda;
816     a_offset = 1 + a_dim1 * 1;
817     a -= a_offset;
818     --s;
819     u_dim1 = *ldu;
820     u_offset = 1 + u_dim1 * 1;
821     u -= u_offset;
822     vt_dim1 = *ldvt;
823     vt_offset = 1 + vt_dim1 * 1;
824     vt -= vt_offset;
825     --work;
826     --iwork;
827
828     /* Function Body */
829     *info = 0;
830     minmn = f2cmin(*m,*n);
831     wntqa = lsame_(jobz, "A");
832     wntqs = lsame_(jobz, "S");
833     wntqas = wntqa || wntqs;
834     wntqo = lsame_(jobz, "O");
835     wntqn = lsame_(jobz, "N");
836     lquery = *lwork == -1;
837
838     if (! (wntqa || wntqs || wntqo || wntqn)) {
839         *info = -1;
840     } else if (*m < 0) {
841         *info = -2;
842     } else if (*n < 0) {
843         *info = -3;
844     } else if (*lda < f2cmax(1,*m)) {
845         *info = -5;
846     } else if (*ldu < 1 || wntqas && *ldu < *m || wntqo && *m < *n && *ldu < *
847             m) {
848         *info = -8;
849     } else if (*ldvt < 1 || wntqa && *ldvt < *n || wntqs && *ldvt < minmn || 
850             wntqo && *m >= *n && *ldvt < *n) {
851         *info = -10;
852     }
853
854 /*     Compute workspace */
855 /*       Note: Comments in the code beginning "Workspace:" describe the */
856 /*       minimal amount of workspace allocated at that point in the code, */
857 /*       as well as the preferred amount for good performance. */
858 /*       NB refers to the optimal block size for the immediately */
859 /*       following subroutine, as returned by ILAENV. */
860
861     if (*info == 0) {
862         minwrk = 1;
863         maxwrk = 1;
864         bdspac = 0;
865         mnthr = (integer) (minmn * 11. / 6.);
866         if (*m >= *n && minmn > 0) {
867
868 /*           Compute space needed for DBDSDC */
869
870             if (wntqn) {
871 /*              dbdsdc needs only 4*N (or 6*N for uplo=L for LAPACK <= 3.6) */
872 /*              keep 7*N for backwards compatibility. */
873                 bdspac = *n * 7;
874             } else {
875                 bdspac = *n * 3 * *n + (*n << 2);
876             }
877
878 /*           Compute space preferred for each routine */
879             dgebrd_(m, n, dum, m, dum, dum, dum, dum, dum, &c_n1, &ierr);
880             lwork_dgebrd_mn__ = (integer) dum[0];
881
882             dgebrd_(n, n, dum, n, dum, dum, dum, dum, dum, &c_n1, &ierr);
883             lwork_dgebrd_nn__ = (integer) dum[0];
884
885             dgeqrf_(m, n, dum, m, dum, dum, &c_n1, &ierr);
886             lwork_dgeqrf_mn__ = (integer) dum[0];
887
888             dorgbr_("Q", n, n, n, dum, n, dum, dum, &c_n1, &ierr);
889             lwork_dorgbr_q_nn__ = (integer) dum[0];
890
891             dorgqr_(m, m, n, dum, m, dum, dum, &c_n1, &ierr);
892             lwork_dorgqr_mm__ = (integer) dum[0];
893
894             dorgqr_(m, n, n, dum, m, dum, dum, &c_n1, &ierr);
895             lwork_dorgqr_mn__ = (integer) dum[0];
896
897             dormbr_("P", "R", "T", n, n, n, dum, n, dum, dum, n, dum, &c_n1, &
898                     ierr);
899             lwork_dormbr_prt_nn__ = (integer) dum[0];
900
901             dormbr_("Q", "L", "N", n, n, n, dum, n, dum, dum, n, dum, &c_n1, &
902                     ierr);
903             lwork_dormbr_qln_nn__ = (integer) dum[0];
904
905             dormbr_("Q", "L", "N", m, n, n, dum, m, dum, dum, m, dum, &c_n1, &
906                     ierr);
907             lwork_dormbr_qln_mn__ = (integer) dum[0];
908
909             dormbr_("Q", "L", "N", m, m, n, dum, m, dum, dum, m, dum, &c_n1, &
910                     ierr);
911             lwork_dormbr_qln_mm__ = (integer) dum[0];
912
913             if (*m >= mnthr) {
914                 if (wntqn) {
915
916 /*                 Path 1 (M >> N, JOBZ='N') */
917
918                     wrkbl = *n + lwork_dgeqrf_mn__;
919 /* Computing MAX */
920                     i__1 = wrkbl, i__2 = *n * 3 + lwork_dgebrd_nn__;
921                     wrkbl = f2cmax(i__1,i__2);
922 /* Computing MAX */
923                     i__1 = wrkbl, i__2 = bdspac + *n;
924                     maxwrk = f2cmax(i__1,i__2);
925                     minwrk = bdspac + *n;
926                 } else if (wntqo) {
927
928 /*                 Path 2 (M >> N, JOBZ='O') */
929
930                     wrkbl = *n + lwork_dgeqrf_mn__;
931 /* Computing MAX */
932                     i__1 = wrkbl, i__2 = *n + lwork_dorgqr_mn__;
933                     wrkbl = f2cmax(i__1,i__2);
934 /* Computing MAX */
935                     i__1 = wrkbl, i__2 = *n * 3 + lwork_dgebrd_nn__;
936                     wrkbl = f2cmax(i__1,i__2);
937 /* Computing MAX */
938                     i__1 = wrkbl, i__2 = *n * 3 + lwork_dormbr_qln_nn__;
939                     wrkbl = f2cmax(i__1,i__2);
940 /* Computing MAX */
941                     i__1 = wrkbl, i__2 = *n * 3 + lwork_dormbr_prt_nn__;
942                     wrkbl = f2cmax(i__1,i__2);
943 /* Computing MAX */
944                     i__1 = wrkbl, i__2 = *n * 3 + bdspac;
945                     wrkbl = f2cmax(i__1,i__2);
946                     maxwrk = wrkbl + (*n << 1) * *n;
947                     minwrk = bdspac + (*n << 1) * *n + *n * 3;
948                 } else if (wntqs) {
949
950 /*                 Path 3 (M >> N, JOBZ='S') */
951
952                     wrkbl = *n + lwork_dgeqrf_mn__;
953 /* Computing MAX */
954                     i__1 = wrkbl, i__2 = *n + lwork_dorgqr_mn__;
955                     wrkbl = f2cmax(i__1,i__2);
956 /* Computing MAX */
957                     i__1 = wrkbl, i__2 = *n * 3 + lwork_dgebrd_nn__;
958                     wrkbl = f2cmax(i__1,i__2);
959 /* Computing MAX */
960                     i__1 = wrkbl, i__2 = *n * 3 + lwork_dormbr_qln_nn__;
961                     wrkbl = f2cmax(i__1,i__2);
962 /* Computing MAX */
963                     i__1 = wrkbl, i__2 = *n * 3 + lwork_dormbr_prt_nn__;
964                     wrkbl = f2cmax(i__1,i__2);
965 /* Computing MAX */
966                     i__1 = wrkbl, i__2 = *n * 3 + bdspac;
967                     wrkbl = f2cmax(i__1,i__2);
968                     maxwrk = wrkbl + *n * *n;
969                     minwrk = bdspac + *n * *n + *n * 3;
970                 } else if (wntqa) {
971
972 /*                 Path 4 (M >> N, JOBZ='A') */
973
974                     wrkbl = *n + lwork_dgeqrf_mn__;
975 /* Computing MAX */
976                     i__1 = wrkbl, i__2 = *n + lwork_dorgqr_mm__;
977                     wrkbl = f2cmax(i__1,i__2);
978 /* Computing MAX */
979                     i__1 = wrkbl, i__2 = *n * 3 + lwork_dgebrd_nn__;
980                     wrkbl = f2cmax(i__1,i__2);
981 /* Computing MAX */
982                     i__1 = wrkbl, i__2 = *n * 3 + lwork_dormbr_qln_nn__;
983                     wrkbl = f2cmax(i__1,i__2);
984 /* Computing MAX */
985                     i__1 = wrkbl, i__2 = *n * 3 + lwork_dormbr_prt_nn__;
986                     wrkbl = f2cmax(i__1,i__2);
987 /* Computing MAX */
988                     i__1 = wrkbl, i__2 = *n * 3 + bdspac;
989                     wrkbl = f2cmax(i__1,i__2);
990                     maxwrk = wrkbl + *n * *n;
991 /* Computing MAX */
992                     i__1 = *n * 3 + bdspac, i__2 = *n + *m;
993                     minwrk = *n * *n + f2cmax(i__1,i__2);
994                 }
995             } else {
996
997 /*              Path 5 (M >= N, but not much larger) */
998
999                 wrkbl = *n * 3 + lwork_dgebrd_mn__;
1000                 if (wntqn) {
1001 /*                 Path 5n (M >= N, jobz='N') */
1002 /* Computing MAX */
1003                     i__1 = wrkbl, i__2 = *n * 3 + bdspac;
1004                     maxwrk = f2cmax(i__1,i__2);
1005                     minwrk = *n * 3 + f2cmax(*m,bdspac);
1006                 } else if (wntqo) {
1007 /*                 Path 5o (M >= N, jobz='O') */
1008 /* Computing MAX */
1009                     i__1 = wrkbl, i__2 = *n * 3 + lwork_dormbr_prt_nn__;
1010                     wrkbl = f2cmax(i__1,i__2);
1011 /* Computing MAX */
1012                     i__1 = wrkbl, i__2 = *n * 3 + lwork_dormbr_qln_mn__;
1013                     wrkbl = f2cmax(i__1,i__2);
1014 /* Computing MAX */
1015                     i__1 = wrkbl, i__2 = *n * 3 + bdspac;
1016                     wrkbl = f2cmax(i__1,i__2);
1017                     maxwrk = wrkbl + *m * *n;
1018 /* Computing MAX */
1019                     i__1 = *m, i__2 = *n * *n + bdspac;
1020                     minwrk = *n * 3 + f2cmax(i__1,i__2);
1021                 } else if (wntqs) {
1022 /*                 Path 5s (M >= N, jobz='S') */
1023 /* Computing MAX */
1024                     i__1 = wrkbl, i__2 = *n * 3 + lwork_dormbr_qln_mn__;
1025                     wrkbl = f2cmax(i__1,i__2);
1026 /* Computing MAX */
1027                     i__1 = wrkbl, i__2 = *n * 3 + lwork_dormbr_prt_nn__;
1028                     wrkbl = f2cmax(i__1,i__2);
1029 /* Computing MAX */
1030                     i__1 = wrkbl, i__2 = *n * 3 + bdspac;
1031                     maxwrk = f2cmax(i__1,i__2);
1032                     minwrk = *n * 3 + f2cmax(*m,bdspac);
1033                 } else if (wntqa) {
1034 /*                 Path 5a (M >= N, jobz='A') */
1035 /* Computing MAX */
1036                     i__1 = wrkbl, i__2 = *n * 3 + lwork_dormbr_qln_mm__;
1037                     wrkbl = f2cmax(i__1,i__2);
1038 /* Computing MAX */
1039                     i__1 = wrkbl, i__2 = *n * 3 + lwork_dormbr_prt_nn__;
1040                     wrkbl = f2cmax(i__1,i__2);
1041 /* Computing MAX */
1042                     i__1 = wrkbl, i__2 = *n * 3 + bdspac;
1043                     maxwrk = f2cmax(i__1,i__2);
1044                     minwrk = *n * 3 + f2cmax(*m,bdspac);
1045                 }
1046             }
1047         } else if (minmn > 0) {
1048
1049 /*           Compute space needed for DBDSDC */
1050
1051             if (wntqn) {
1052 /*              dbdsdc needs only 4*N (or 6*N for uplo=L for LAPACK <= 3.6) */
1053 /*              keep 7*N for backwards compatibility. */
1054                 bdspac = *m * 7;
1055             } else {
1056                 bdspac = *m * 3 * *m + (*m << 2);
1057             }
1058
1059 /*           Compute space preferred for each routine */
1060             dgebrd_(m, n, dum, m, dum, dum, dum, dum, dum, &c_n1, &ierr);
1061             lwork_dgebrd_mn__ = (integer) dum[0];
1062
1063             dgebrd_(m, m, &a[a_offset], m, &s[1], dum, dum, dum, dum, &c_n1, &
1064                     ierr);
1065             lwork_dgebrd_mm__ = (integer) dum[0];
1066
1067             dgelqf_(m, n, &a[a_offset], m, dum, dum, &c_n1, &ierr);
1068             lwork_dgelqf_mn__ = (integer) dum[0];
1069
1070             dorglq_(n, n, m, dum, n, dum, dum, &c_n1, &ierr);
1071             lwork_dorglq_nn__ = (integer) dum[0];
1072
1073             dorglq_(m, n, m, &a[a_offset], m, dum, dum, &c_n1, &ierr);
1074             lwork_dorglq_mn__ = (integer) dum[0];
1075
1076             dorgbr_("P", m, m, m, &a[a_offset], n, dum, dum, &c_n1, &ierr);
1077             lwork_dorgbr_p_mm__ = (integer) dum[0];
1078
1079             dormbr_("P", "R", "T", m, m, m, dum, m, dum, dum, m, dum, &c_n1, &
1080                     ierr);
1081             lwork_dormbr_prt_mm__ = (integer) dum[0];
1082
1083             dormbr_("P", "R", "T", m, n, m, dum, m, dum, dum, m, dum, &c_n1, &
1084                     ierr);
1085             lwork_dormbr_prt_mn__ = (integer) dum[0];
1086
1087             dormbr_("P", "R", "T", n, n, m, dum, n, dum, dum, n, dum, &c_n1, &
1088                     ierr);
1089             lwork_dormbr_prt_nn__ = (integer) dum[0];
1090
1091             dormbr_("Q", "L", "N", m, m, m, dum, m, dum, dum, m, dum, &c_n1, &
1092                     ierr);
1093             lwork_dormbr_qln_mm__ = (integer) dum[0];
1094
1095             if (*n >= mnthr) {
1096                 if (wntqn) {
1097
1098 /*                 Path 1t (N >> M, JOBZ='N') */
1099
1100                     wrkbl = *m + lwork_dgelqf_mn__;
1101 /* Computing MAX */
1102                     i__1 = wrkbl, i__2 = *m * 3 + lwork_dgebrd_mm__;
1103                     wrkbl = f2cmax(i__1,i__2);
1104 /* Computing MAX */
1105                     i__1 = wrkbl, i__2 = bdspac + *m;
1106                     maxwrk = f2cmax(i__1,i__2);
1107                     minwrk = bdspac + *m;
1108                 } else if (wntqo) {
1109
1110 /*                 Path 2t (N >> M, JOBZ='O') */
1111
1112                     wrkbl = *m + lwork_dgelqf_mn__;
1113 /* Computing MAX */
1114                     i__1 = wrkbl, i__2 = *m + lwork_dorglq_mn__;
1115                     wrkbl = f2cmax(i__1,i__2);
1116 /* Computing MAX */
1117                     i__1 = wrkbl, i__2 = *m * 3 + lwork_dgebrd_mm__;
1118                     wrkbl = f2cmax(i__1,i__2);
1119 /* Computing MAX */
1120                     i__1 = wrkbl, i__2 = *m * 3 + lwork_dormbr_qln_mm__;
1121                     wrkbl = f2cmax(i__1,i__2);
1122 /* Computing MAX */
1123                     i__1 = wrkbl, i__2 = *m * 3 + lwork_dormbr_prt_mm__;
1124                     wrkbl = f2cmax(i__1,i__2);
1125 /* Computing MAX */
1126                     i__1 = wrkbl, i__2 = *m * 3 + bdspac;
1127                     wrkbl = f2cmax(i__1,i__2);
1128                     maxwrk = wrkbl + (*m << 1) * *m;
1129                     minwrk = bdspac + (*m << 1) * *m + *m * 3;
1130                 } else if (wntqs) {
1131
1132 /*                 Path 3t (N >> M, JOBZ='S') */
1133
1134                     wrkbl = *m + lwork_dgelqf_mn__;
1135 /* Computing MAX */
1136                     i__1 = wrkbl, i__2 = *m + lwork_dorglq_mn__;
1137                     wrkbl = f2cmax(i__1,i__2);
1138 /* Computing MAX */
1139                     i__1 = wrkbl, i__2 = *m * 3 + lwork_dgebrd_mm__;
1140                     wrkbl = f2cmax(i__1,i__2);
1141 /* Computing MAX */
1142                     i__1 = wrkbl, i__2 = *m * 3 + lwork_dormbr_qln_mm__;
1143                     wrkbl = f2cmax(i__1,i__2);
1144 /* Computing MAX */
1145                     i__1 = wrkbl, i__2 = *m * 3 + lwork_dormbr_prt_mm__;
1146                     wrkbl = f2cmax(i__1,i__2);
1147 /* Computing MAX */
1148                     i__1 = wrkbl, i__2 = *m * 3 + bdspac;
1149                     wrkbl = f2cmax(i__1,i__2);
1150                     maxwrk = wrkbl + *m * *m;
1151                     minwrk = bdspac + *m * *m + *m * 3;
1152                 } else if (wntqa) {
1153
1154 /*                 Path 4t (N >> M, JOBZ='A') */
1155
1156                     wrkbl = *m + lwork_dgelqf_mn__;
1157 /* Computing MAX */
1158                     i__1 = wrkbl, i__2 = *m + lwork_dorglq_nn__;
1159                     wrkbl = f2cmax(i__1,i__2);
1160 /* Computing MAX */
1161                     i__1 = wrkbl, i__2 = *m * 3 + lwork_dgebrd_mm__;
1162                     wrkbl = f2cmax(i__1,i__2);
1163 /* Computing MAX */
1164                     i__1 = wrkbl, i__2 = *m * 3 + lwork_dormbr_qln_mm__;
1165                     wrkbl = f2cmax(i__1,i__2);
1166 /* Computing MAX */
1167                     i__1 = wrkbl, i__2 = *m * 3 + lwork_dormbr_prt_mm__;
1168                     wrkbl = f2cmax(i__1,i__2);
1169 /* Computing MAX */
1170                     i__1 = wrkbl, i__2 = *m * 3 + bdspac;
1171                     wrkbl = f2cmax(i__1,i__2);
1172                     maxwrk = wrkbl + *m * *m;
1173 /* Computing MAX */
1174                     i__1 = *m * 3 + bdspac, i__2 = *m + *n;
1175                     minwrk = *m * *m + f2cmax(i__1,i__2);
1176                 }
1177             } else {
1178
1179 /*              Path 5t (N > M, but not much larger) */
1180
1181                 wrkbl = *m * 3 + lwork_dgebrd_mn__;
1182                 if (wntqn) {
1183 /*                 Path 5tn (N > M, jobz='N') */
1184 /* Computing MAX */
1185                     i__1 = wrkbl, i__2 = *m * 3 + bdspac;
1186                     maxwrk = f2cmax(i__1,i__2);
1187                     minwrk = *m * 3 + f2cmax(*n,bdspac);
1188                 } else if (wntqo) {
1189 /*                 Path 5to (N > M, jobz='O') */
1190 /* Computing MAX */
1191                     i__1 = wrkbl, i__2 = *m * 3 + lwork_dormbr_qln_mm__;
1192                     wrkbl = f2cmax(i__1,i__2);
1193 /* Computing MAX */
1194                     i__1 = wrkbl, i__2 = *m * 3 + lwork_dormbr_prt_mn__;
1195                     wrkbl = f2cmax(i__1,i__2);
1196 /* Computing MAX */
1197                     i__1 = wrkbl, i__2 = *m * 3 + bdspac;
1198                     wrkbl = f2cmax(i__1,i__2);
1199                     maxwrk = wrkbl + *m * *n;
1200 /* Computing MAX */
1201                     i__1 = *n, i__2 = *m * *m + bdspac;
1202                     minwrk = *m * 3 + f2cmax(i__1,i__2);
1203                 } else if (wntqs) {
1204 /*                 Path 5ts (N > M, jobz='S') */
1205 /* Computing MAX */
1206                     i__1 = wrkbl, i__2 = *m * 3 + lwork_dormbr_qln_mm__;
1207                     wrkbl = f2cmax(i__1,i__2);
1208 /* Computing MAX */
1209                     i__1 = wrkbl, i__2 = *m * 3 + lwork_dormbr_prt_mn__;
1210                     wrkbl = f2cmax(i__1,i__2);
1211 /* Computing MAX */
1212                     i__1 = wrkbl, i__2 = *m * 3 + bdspac;
1213                     maxwrk = f2cmax(i__1,i__2);
1214                     minwrk = *m * 3 + f2cmax(*n,bdspac);
1215                 } else if (wntqa) {
1216 /*                 Path 5ta (N > M, jobz='A') */
1217 /* Computing MAX */
1218                     i__1 = wrkbl, i__2 = *m * 3 + lwork_dormbr_qln_mm__;
1219                     wrkbl = f2cmax(i__1,i__2);
1220 /* Computing MAX */
1221                     i__1 = wrkbl, i__2 = *m * 3 + lwork_dormbr_prt_nn__;
1222                     wrkbl = f2cmax(i__1,i__2);
1223 /* Computing MAX */
1224                     i__1 = wrkbl, i__2 = *m * 3 + bdspac;
1225                     maxwrk = f2cmax(i__1,i__2);
1226                     minwrk = *m * 3 + f2cmax(*n,bdspac);
1227                 }
1228             }
1229         }
1230         maxwrk = f2cmax(maxwrk,minwrk);
1231         work[1] = (doublereal) maxwrk;
1232
1233         if (*lwork < minwrk && ! lquery) {
1234             *info = -12;
1235         }
1236     }
1237
1238     if (*info != 0) {
1239         i__1 = -(*info);
1240         xerbla_("DGESDD", &i__1, (ftnlen)6);
1241         return 0;
1242     } else if (lquery) {
1243         return 0;
1244     }
1245
1246 /*     Quick return if possible */
1247
1248     if (*m == 0 || *n == 0) {
1249         return 0;
1250     }
1251
1252 /*     Get machine constants */
1253
1254     eps = dlamch_("P");
1255     smlnum = sqrt(dlamch_("S")) / eps;
1256     bignum = 1. / smlnum;
1257
1258 /*     Scale A if f2cmax element outside range [SMLNUM,BIGNUM] */
1259
1260     anrm = dlange_("M", m, n, &a[a_offset], lda, dum);
1261     if (disnan_(&anrm)) {
1262         *info = -4;
1263         return 0;
1264     }
1265     iscl = 0;
1266     if (anrm > 0. && anrm < smlnum) {
1267         iscl = 1;
1268         dlascl_("G", &c__0, &c__0, &anrm, &smlnum, m, n, &a[a_offset], lda, &
1269                 ierr);
1270     } else if (anrm > bignum) {
1271         iscl = 1;
1272         dlascl_("G", &c__0, &c__0, &anrm, &bignum, m, n, &a[a_offset], lda, &
1273                 ierr);
1274     }
1275
1276     if (*m >= *n) {
1277
1278 /*        A has at least as many rows as columns. If A has sufficiently */
1279 /*        more rows than columns, first reduce using the QR */
1280 /*        decomposition (if sufficient workspace available) */
1281
1282         if (*m >= mnthr) {
1283
1284             if (wntqn) {
1285
1286 /*              Path 1 (M >> N, JOBZ='N') */
1287 /*              No singular vectors to be computed */
1288
1289                 itau = 1;
1290                 nwork = itau + *n;
1291
1292 /*              Compute A=Q*R */
1293 /*              Workspace: need   N [tau] + N    [work] */
1294 /*              Workspace: prefer N [tau] + N*NB [work] */
1295
1296                 i__1 = *lwork - nwork + 1;
1297                 dgeqrf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
1298                         i__1, &ierr);
1299
1300 /*              Zero out below R */
1301
1302                 i__1 = *n - 1;
1303                 i__2 = *n - 1;
1304                 dlaset_("L", &i__1, &i__2, &c_b63, &c_b63, &a[a_dim1 + 2], 
1305                         lda);
1306                 ie = 1;
1307                 itauq = ie + *n;
1308                 itaup = itauq + *n;
1309                 nwork = itaup + *n;
1310
1311 /*              Bidiagonalize R in A */
1312 /*              Workspace: need   3*N [e, tauq, taup] + N      [work] */
1313 /*              Workspace: prefer 3*N [e, tauq, taup] + 2*N*NB [work] */
1314
1315                 i__1 = *lwork - nwork + 1;
1316                 dgebrd_(n, n, &a[a_offset], lda, &s[1], &work[ie], &work[
1317                         itauq], &work[itaup], &work[nwork], &i__1, &ierr);
1318                 nwork = ie + *n;
1319
1320 /*              Perform bidiagonal SVD, computing singular values only */
1321 /*              Workspace: need   N [e] + BDSPAC */
1322
1323                 dbdsdc_("U", "N", n, &s[1], &work[ie], dum, &c__1, dum, &c__1,
1324                          dum, idum, &work[nwork], &iwork[1], info);
1325
1326             } else if (wntqo) {
1327
1328 /*              Path 2 (M >> N, JOBZ = 'O') */
1329 /*              N left singular vectors to be overwritten on A and */
1330 /*              N right singular vectors to be computed in VT */
1331
1332                 ir = 1;
1333
1334 /*              WORK(IR) is LDWRKR by N */
1335
1336                 if (*lwork >= *lda * *n + *n * *n + *n * 3 + bdspac) {
1337                     ldwrkr = *lda;
1338                 } else {
1339                     ldwrkr = (*lwork - *n * *n - *n * 3 - bdspac) / *n;
1340                 }
1341                 itau = ir + ldwrkr * *n;
1342                 nwork = itau + *n;
1343
1344 /*              Compute A=Q*R */
1345 /*              Workspace: need   N*N [R] + N [tau] + N    [work] */
1346 /*              Workspace: prefer N*N [R] + N [tau] + N*NB [work] */
1347
1348                 i__1 = *lwork - nwork + 1;
1349                 dgeqrf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
1350                         i__1, &ierr);
1351
1352 /*              Copy R to WORK(IR), zeroing out below it */
1353
1354                 dlacpy_("U", n, n, &a[a_offset], lda, &work[ir], &ldwrkr);
1355                 i__1 = *n - 1;
1356                 i__2 = *n - 1;
1357                 dlaset_("L", &i__1, &i__2, &c_b63, &c_b63, &work[ir + 1], &
1358                         ldwrkr);
1359
1360 /*              Generate Q in A */
1361 /*              Workspace: need   N*N [R] + N [tau] + N    [work] */
1362 /*              Workspace: prefer N*N [R] + N [tau] + N*NB [work] */
1363
1364                 i__1 = *lwork - nwork + 1;
1365                 dorgqr_(m, n, n, &a[a_offset], lda, &work[itau], &work[nwork],
1366                          &i__1, &ierr);
1367                 ie = itau;
1368                 itauq = ie + *n;
1369                 itaup = itauq + *n;
1370                 nwork = itaup + *n;
1371
1372 /*              Bidiagonalize R in WORK(IR) */
1373 /*              Workspace: need   N*N [R] + 3*N [e, tauq, taup] + N      [work] */
1374 /*              Workspace: prefer N*N [R] + 3*N [e, tauq, taup] + 2*N*NB [work] */
1375
1376                 i__1 = *lwork - nwork + 1;
1377                 dgebrd_(n, n, &work[ir], &ldwrkr, &s[1], &work[ie], &work[
1378                         itauq], &work[itaup], &work[nwork], &i__1, &ierr);
1379
1380 /*              WORK(IU) is N by N */
1381
1382                 iu = nwork;
1383                 nwork = iu + *n * *n;
1384
1385 /*              Perform bidiagonal SVD, computing left singular vectors */
1386 /*              of bidiagonal matrix in WORK(IU) and computing right */
1387 /*              singular vectors of bidiagonal matrix in VT */
1388 /*              Workspace: need   N*N [R] + 3*N [e, tauq, taup] + N*N [U] + BDSPAC */
1389
1390                 dbdsdc_("U", "I", n, &s[1], &work[ie], &work[iu], n, &vt[
1391                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
1392                         info);
1393
1394 /*              Overwrite WORK(IU) by left singular vectors of R */
1395 /*              and VT by right singular vectors of R */
1396 /*              Workspace: need   N*N [R] + 3*N [e, tauq, taup] + N*N [U] + N    [work] */
1397 /*              Workspace: prefer N*N [R] + 3*N [e, tauq, taup] + N*N [U] + N*NB [work] */
1398
1399                 i__1 = *lwork - nwork + 1;
1400                 dormbr_("Q", "L", "N", n, n, n, &work[ir], &ldwrkr, &work[
1401                         itauq], &work[iu], n, &work[nwork], &i__1, &ierr);
1402                 i__1 = *lwork - nwork + 1;
1403                 dormbr_("P", "R", "T", n, n, n, &work[ir], &ldwrkr, &work[
1404                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__1, &
1405                         ierr);
1406
1407 /*              Multiply Q in A by left singular vectors of R in */
1408 /*              WORK(IU), storing result in WORK(IR) and copying to A */
1409 /*              Workspace: need   N*N [R] + 3*N [e, tauq, taup] + N*N [U] */
1410 /*              Workspace: prefer M*N [R] + 3*N [e, tauq, taup] + N*N [U] */
1411
1412                 i__1 = *m;
1413                 i__2 = ldwrkr;
1414                 for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += 
1415                         i__2) {
1416 /* Computing MIN */
1417                     i__3 = *m - i__ + 1;
1418                     chunk = f2cmin(i__3,ldwrkr);
1419                     dgemm_("N", "N", &chunk, n, n, &c_b84, &a[i__ + a_dim1], 
1420                             lda, &work[iu], n, &c_b63, &work[ir], &ldwrkr);
1421                     dlacpy_("F", &chunk, n, &work[ir], &ldwrkr, &a[i__ + 
1422                             a_dim1], lda);
1423 /* L10: */
1424                 }
1425
1426             } else if (wntqs) {
1427
1428 /*              Path 3 (M >> N, JOBZ='S') */
1429 /*              N left singular vectors to be computed in U and */
1430 /*              N right singular vectors to be computed in VT */
1431
1432                 ir = 1;
1433
1434 /*              WORK(IR) is N by N */
1435
1436                 ldwrkr = *n;
1437                 itau = ir + ldwrkr * *n;
1438                 nwork = itau + *n;
1439
1440 /*              Compute A=Q*R */
1441 /*              Workspace: need   N*N [R] + N [tau] + N    [work] */
1442 /*              Workspace: prefer N*N [R] + N [tau] + N*NB [work] */
1443
1444                 i__2 = *lwork - nwork + 1;
1445                 dgeqrf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
1446                         i__2, &ierr);
1447
1448 /*              Copy R to WORK(IR), zeroing out below it */
1449
1450                 dlacpy_("U", n, n, &a[a_offset], lda, &work[ir], &ldwrkr);
1451                 i__2 = *n - 1;
1452                 i__1 = *n - 1;
1453                 dlaset_("L", &i__2, &i__1, &c_b63, &c_b63, &work[ir + 1], &
1454                         ldwrkr);
1455
1456 /*              Generate Q in A */
1457 /*              Workspace: need   N*N [R] + N [tau] + N    [work] */
1458 /*              Workspace: prefer N*N [R] + N [tau] + N*NB [work] */
1459
1460                 i__2 = *lwork - nwork + 1;
1461                 dorgqr_(m, n, n, &a[a_offset], lda, &work[itau], &work[nwork],
1462                          &i__2, &ierr);
1463                 ie = itau;
1464                 itauq = ie + *n;
1465                 itaup = itauq + *n;
1466                 nwork = itaup + *n;
1467
1468 /*              Bidiagonalize R in WORK(IR) */
1469 /*              Workspace: need   N*N [R] + 3*N [e, tauq, taup] + N      [work] */
1470 /*              Workspace: prefer N*N [R] + 3*N [e, tauq, taup] + 2*N*NB [work] */
1471
1472                 i__2 = *lwork - nwork + 1;
1473                 dgebrd_(n, n, &work[ir], &ldwrkr, &s[1], &work[ie], &work[
1474                         itauq], &work[itaup], &work[nwork], &i__2, &ierr);
1475
1476 /*              Perform bidiagonal SVD, computing left singular vectors */
1477 /*              of bidiagoal matrix in U and computing right singular */
1478 /*              vectors of bidiagonal matrix in VT */
1479 /*              Workspace: need   N*N [R] + 3*N [e, tauq, taup] + BDSPAC */
1480
1481                 dbdsdc_("U", "I", n, &s[1], &work[ie], &u[u_offset], ldu, &vt[
1482                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
1483                         info);
1484
1485 /*              Overwrite U by left singular vectors of R and VT */
1486 /*              by right singular vectors of R */
1487 /*              Workspace: need   N*N [R] + 3*N [e, tauq, taup] + N    [work] */
1488 /*              Workspace: prefer N*N [R] + 3*N [e, tauq, taup] + N*NB [work] */
1489
1490                 i__2 = *lwork - nwork + 1;
1491                 dormbr_("Q", "L", "N", n, n, n, &work[ir], &ldwrkr, &work[
1492                         itauq], &u[u_offset], ldu, &work[nwork], &i__2, &ierr);
1493
1494                 i__2 = *lwork - nwork + 1;
1495                 dormbr_("P", "R", "T", n, n, n, &work[ir], &ldwrkr, &work[
1496                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__2, &
1497                         ierr);
1498
1499 /*              Multiply Q in A by left singular vectors of R in */
1500 /*              WORK(IR), storing result in U */
1501 /*              Workspace: need   N*N [R] */
1502
1503                 dlacpy_("F", n, n, &u[u_offset], ldu, &work[ir], &ldwrkr);
1504                 dgemm_("N", "N", m, n, n, &c_b84, &a[a_offset], lda, &work[ir]
1505                         , &ldwrkr, &c_b63, &u[u_offset], ldu);
1506
1507             } else if (wntqa) {
1508
1509 /*              Path 4 (M >> N, JOBZ='A') */
1510 /*              M left singular vectors to be computed in U and */
1511 /*              N right singular vectors to be computed in VT */
1512
1513                 iu = 1;
1514
1515 /*              WORK(IU) is N by N */
1516
1517                 ldwrku = *n;
1518                 itau = iu + ldwrku * *n;
1519                 nwork = itau + *n;
1520
1521 /*              Compute A=Q*R, copying result to U */
1522 /*              Workspace: need   N*N [U] + N [tau] + N    [work] */
1523 /*              Workspace: prefer N*N [U] + N [tau] + N*NB [work] */
1524
1525                 i__2 = *lwork - nwork + 1;
1526                 dgeqrf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
1527                         i__2, &ierr);
1528                 dlacpy_("L", m, n, &a[a_offset], lda, &u[u_offset], ldu);
1529
1530 /*              Generate Q in U */
1531 /*              Workspace: need   N*N [U] + N [tau] + M    [work] */
1532 /*              Workspace: prefer N*N [U] + N [tau] + M*NB [work] */
1533                 i__2 = *lwork - nwork + 1;
1534                 dorgqr_(m, m, n, &u[u_offset], ldu, &work[itau], &work[nwork],
1535                          &i__2, &ierr);
1536
1537 /*              Produce R in A, zeroing out other entries */
1538
1539                 i__2 = *n - 1;
1540                 i__1 = *n - 1;
1541                 dlaset_("L", &i__2, &i__1, &c_b63, &c_b63, &a[a_dim1 + 2], 
1542                         lda);
1543                 ie = itau;
1544                 itauq = ie + *n;
1545                 itaup = itauq + *n;
1546                 nwork = itaup + *n;
1547
1548 /*              Bidiagonalize R in A */
1549 /*              Workspace: need   N*N [U] + 3*N [e, tauq, taup] + N      [work] */
1550 /*              Workspace: prefer N*N [U] + 3*N [e, tauq, taup] + 2*N*NB [work] */
1551
1552                 i__2 = *lwork - nwork + 1;
1553                 dgebrd_(n, n, &a[a_offset], lda, &s[1], &work[ie], &work[
1554                         itauq], &work[itaup], &work[nwork], &i__2, &ierr);
1555
1556 /*              Perform bidiagonal SVD, computing left singular vectors */
1557 /*              of bidiagonal matrix in WORK(IU) and computing right */
1558 /*              singular vectors of bidiagonal matrix in VT */
1559 /*              Workspace: need   N*N [U] + 3*N [e, tauq, taup] + BDSPAC */
1560
1561                 dbdsdc_("U", "I", n, &s[1], &work[ie], &work[iu], n, &vt[
1562                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
1563                         info);
1564
1565 /*              Overwrite WORK(IU) by left singular vectors of R and VT */
1566 /*              by right singular vectors of R */
1567 /*              Workspace: need   N*N [U] + 3*N [e, tauq, taup] + N    [work] */
1568 /*              Workspace: prefer N*N [U] + 3*N [e, tauq, taup] + N*NB [work] */
1569
1570                 i__2 = *lwork - nwork + 1;
1571                 dormbr_("Q", "L", "N", n, n, n, &a[a_offset], lda, &work[
1572                         itauq], &work[iu], &ldwrku, &work[nwork], &i__2, &
1573                         ierr);
1574                 i__2 = *lwork - nwork + 1;
1575                 dormbr_("P", "R", "T", n, n, n, &a[a_offset], lda, &work[
1576                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__2, &
1577                         ierr);
1578
1579 /*              Multiply Q in U by left singular vectors of R in */
1580 /*              WORK(IU), storing result in A */
1581 /*              Workspace: need   N*N [U] */
1582
1583                 dgemm_("N", "N", m, n, n, &c_b84, &u[u_offset], ldu, &work[iu]
1584                         , &ldwrku, &c_b63, &a[a_offset], lda);
1585
1586 /*              Copy left singular vectors of A from A to U */
1587
1588                 dlacpy_("F", m, n, &a[a_offset], lda, &u[u_offset], ldu);
1589
1590             }
1591
1592         } else {
1593
1594 /*           M .LT. MNTHR */
1595
1596 /*           Path 5 (M >= N, but not much larger) */
1597 /*           Reduce to bidiagonal form without QR decomposition */
1598
1599             ie = 1;
1600             itauq = ie + *n;
1601             itaup = itauq + *n;
1602             nwork = itaup + *n;
1603
1604 /*           Bidiagonalize A */
1605 /*           Workspace: need   3*N [e, tauq, taup] + M        [work] */
1606 /*           Workspace: prefer 3*N [e, tauq, taup] + (M+N)*NB [work] */
1607
1608             i__2 = *lwork - nwork + 1;
1609             dgebrd_(m, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &
1610                     work[itaup], &work[nwork], &i__2, &ierr);
1611             if (wntqn) {
1612
1613 /*              Path 5n (M >= N, JOBZ='N') */
1614 /*              Perform bidiagonal SVD, only computing singular values */
1615 /*              Workspace: need   3*N [e, tauq, taup] + BDSPAC */
1616
1617                 dbdsdc_("U", "N", n, &s[1], &work[ie], dum, &c__1, dum, &c__1,
1618                          dum, idum, &work[nwork], &iwork[1], info);
1619             } else if (wntqo) {
1620 /*              Path 5o (M >= N, JOBZ='O') */
1621                 iu = nwork;
1622                 if (*lwork >= *m * *n + *n * 3 + bdspac) {
1623
1624 /*                 WORK( IU ) is M by N */
1625
1626                     ldwrku = *m;
1627                     nwork = iu + ldwrku * *n;
1628                     dlaset_("F", m, n, &c_b63, &c_b63, &work[iu], &ldwrku);
1629 /*                 IR is unused; silence compile warnings */
1630                     ir = -1;
1631                 } else {
1632
1633 /*                 WORK( IU ) is N by N */
1634
1635                     ldwrku = *n;
1636                     nwork = iu + ldwrku * *n;
1637
1638 /*                 WORK(IR) is LDWRKR by N */
1639
1640                     ir = nwork;
1641                     ldwrkr = (*lwork - *n * *n - *n * 3) / *n;
1642                 }
1643                 nwork = iu + ldwrku * *n;
1644
1645 /*              Perform bidiagonal SVD, computing left singular vectors */
1646 /*              of bidiagonal matrix in WORK(IU) and computing right */
1647 /*              singular vectors of bidiagonal matrix in VT */
1648 /*              Workspace: need   3*N [e, tauq, taup] + N*N [U] + BDSPAC */
1649
1650                 dbdsdc_("U", "I", n, &s[1], &work[ie], &work[iu], &ldwrku, &
1651                         vt[vt_offset], ldvt, dum, idum, &work[nwork], &iwork[
1652                         1], info);
1653
1654 /*              Overwrite VT by right singular vectors of A */
1655 /*              Workspace: need   3*N [e, tauq, taup] + N*N [U] + N    [work] */
1656 /*              Workspace: prefer 3*N [e, tauq, taup] + N*N [U] + N*NB [work] */
1657
1658                 i__2 = *lwork - nwork + 1;
1659                 dormbr_("P", "R", "T", n, n, n, &a[a_offset], lda, &work[
1660                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__2, &
1661                         ierr);
1662
1663                 if (*lwork >= *m * *n + *n * 3 + bdspac) {
1664
1665 /*                 Path 5o-fast */
1666 /*                 Overwrite WORK(IU) by left singular vectors of A */
1667 /*                 Workspace: need   3*N [e, tauq, taup] + M*N [U] + N    [work] */
1668 /*                 Workspace: prefer 3*N [e, tauq, taup] + M*N [U] + N*NB [work] */
1669
1670                     i__2 = *lwork - nwork + 1;
1671                     dormbr_("Q", "L", "N", m, n, n, &a[a_offset], lda, &work[
1672                             itauq], &work[iu], &ldwrku, &work[nwork], &i__2, &
1673                             ierr);
1674
1675 /*                 Copy left singular vectors of A from WORK(IU) to A */
1676
1677                     dlacpy_("F", m, n, &work[iu], &ldwrku, &a[a_offset], lda);
1678                 } else {
1679
1680 /*                 Path 5o-slow */
1681 /*                 Generate Q in A */
1682 /*                 Workspace: need   3*N [e, tauq, taup] + N*N [U] + N    [work] */
1683 /*                 Workspace: prefer 3*N [e, tauq, taup] + N*N [U] + N*NB [work] */
1684
1685                     i__2 = *lwork - nwork + 1;
1686                     dorgbr_("Q", m, n, n, &a[a_offset], lda, &work[itauq], &
1687                             work[nwork], &i__2, &ierr);
1688
1689 /*                 Multiply Q in A by left singular vectors of */
1690 /*                 bidiagonal matrix in WORK(IU), storing result in */
1691 /*                 WORK(IR) and copying to A */
1692 /*                 Workspace: need   3*N [e, tauq, taup] + N*N [U] + NB*N [R] */
1693 /*                 Workspace: prefer 3*N [e, tauq, taup] + N*N [U] + M*N  [R] */
1694
1695                     i__2 = *m;
1696                     i__1 = ldwrkr;
1697                     for (i__ = 1; i__1 < 0 ? i__ >= i__2 : i__ <= i__2; i__ +=
1698                              i__1) {
1699 /* Computing MIN */
1700                         i__3 = *m - i__ + 1;
1701                         chunk = f2cmin(i__3,ldwrkr);
1702                         dgemm_("N", "N", &chunk, n, n, &c_b84, &a[i__ + 
1703                                 a_dim1], lda, &work[iu], &ldwrku, &c_b63, &
1704                                 work[ir], &ldwrkr);
1705                         dlacpy_("F", &chunk, n, &work[ir], &ldwrkr, &a[i__ + 
1706                                 a_dim1], lda);
1707 /* L20: */
1708                     }
1709                 }
1710
1711             } else if (wntqs) {
1712
1713 /*              Path 5s (M >= N, JOBZ='S') */
1714 /*              Perform bidiagonal SVD, computing left singular vectors */
1715 /*              of bidiagonal matrix in U and computing right singular */
1716 /*              vectors of bidiagonal matrix in VT */
1717 /*              Workspace: need   3*N [e, tauq, taup] + BDSPAC */
1718
1719                 dlaset_("F", m, n, &c_b63, &c_b63, &u[u_offset], ldu);
1720                 dbdsdc_("U", "I", n, &s[1], &work[ie], &u[u_offset], ldu, &vt[
1721                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
1722                         info);
1723
1724 /*              Overwrite U by left singular vectors of A and VT */
1725 /*              by right singular vectors of A */
1726 /*              Workspace: need   3*N [e, tauq, taup] + N    [work] */
1727 /*              Workspace: prefer 3*N [e, tauq, taup] + N*NB [work] */
1728
1729                 i__1 = *lwork - nwork + 1;
1730                 dormbr_("Q", "L", "N", m, n, n, &a[a_offset], lda, &work[
1731                         itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
1732                 i__1 = *lwork - nwork + 1;
1733                 dormbr_("P", "R", "T", n, n, n, &a[a_offset], lda, &work[
1734                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__1, &
1735                         ierr);
1736             } else if (wntqa) {
1737
1738 /*              Path 5a (M >= N, JOBZ='A') */
1739 /*              Perform bidiagonal SVD, computing left singular vectors */
1740 /*              of bidiagonal matrix in U and computing right singular */
1741 /*              vectors of bidiagonal matrix in VT */
1742 /*              Workspace: need   3*N [e, tauq, taup] + BDSPAC */
1743
1744                 dlaset_("F", m, m, &c_b63, &c_b63, &u[u_offset], ldu);
1745                 dbdsdc_("U", "I", n, &s[1], &work[ie], &u[u_offset], ldu, &vt[
1746                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
1747                         info);
1748
1749 /*              Set the right corner of U to identity matrix */
1750
1751                 if (*m > *n) {
1752                     i__1 = *m - *n;
1753                     i__2 = *m - *n;
1754                     dlaset_("F", &i__1, &i__2, &c_b63, &c_b84, &u[*n + 1 + (*
1755                             n + 1) * u_dim1], ldu);
1756                 }
1757
1758 /*              Overwrite U by left singular vectors of A and VT */
1759 /*              by right singular vectors of A */
1760 /*              Workspace: need   3*N [e, tauq, taup] + M    [work] */
1761 /*              Workspace: prefer 3*N [e, tauq, taup] + M*NB [work] */
1762
1763                 i__1 = *lwork - nwork + 1;
1764                 dormbr_("Q", "L", "N", m, m, n, &a[a_offset], lda, &work[
1765                         itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
1766                 i__1 = *lwork - nwork + 1;
1767                 dormbr_("P", "R", "T", n, n, m, &a[a_offset], lda, &work[
1768                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__1, &
1769                         ierr);
1770             }
1771
1772         }
1773
1774     } else {
1775
1776 /*        A has more columns than rows. If A has sufficiently more */
1777 /*        columns than rows, first reduce using the LQ decomposition (if */
1778 /*        sufficient workspace available) */
1779
1780         if (*n >= mnthr) {
1781
1782             if (wntqn) {
1783
1784 /*              Path 1t (N >> M, JOBZ='N') */
1785 /*              No singular vectors to be computed */
1786
1787                 itau = 1;
1788                 nwork = itau + *m;
1789
1790 /*              Compute A=L*Q */
1791 /*              Workspace: need   M [tau] + M [work] */
1792 /*              Workspace: prefer M [tau] + M*NB [work] */
1793
1794                 i__1 = *lwork - nwork + 1;
1795                 dgelqf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
1796                         i__1, &ierr);
1797
1798 /*              Zero out above L */
1799
1800                 i__1 = *m - 1;
1801                 i__2 = *m - 1;
1802                 dlaset_("U", &i__1, &i__2, &c_b63, &c_b63, &a[(a_dim1 << 1) + 
1803                         1], lda);
1804                 ie = 1;
1805                 itauq = ie + *m;
1806                 itaup = itauq + *m;
1807                 nwork = itaup + *m;
1808
1809 /*              Bidiagonalize L in A */
1810 /*              Workspace: need   3*M [e, tauq, taup] + M      [work] */
1811 /*              Workspace: prefer 3*M [e, tauq, taup] + 2*M*NB [work] */
1812
1813                 i__1 = *lwork - nwork + 1;
1814                 dgebrd_(m, m, &a[a_offset], lda, &s[1], &work[ie], &work[
1815                         itauq], &work[itaup], &work[nwork], &i__1, &ierr);
1816                 nwork = ie + *m;
1817
1818 /*              Perform bidiagonal SVD, computing singular values only */
1819 /*              Workspace: need   M [e] + BDSPAC */
1820
1821                 dbdsdc_("U", "N", m, &s[1], &work[ie], dum, &c__1, dum, &c__1,
1822                          dum, idum, &work[nwork], &iwork[1], info);
1823
1824             } else if (wntqo) {
1825
1826 /*              Path 2t (N >> M, JOBZ='O') */
1827 /*              M right singular vectors to be overwritten on A and */
1828 /*              M left singular vectors to be computed in U */
1829
1830                 ivt = 1;
1831
1832 /*              WORK(IVT) is M by M */
1833 /*              WORK(IL)  is M by M; it is later resized to M by chunk for gemm */
1834
1835                 il = ivt + *m * *m;
1836                 if (*lwork >= *m * *n + *m * *m + *m * 3 + bdspac) {
1837                     ldwrkl = *m;
1838                     chunk = *n;
1839                 } else {
1840                     ldwrkl = *m;
1841                     chunk = (*lwork - *m * *m) / *m;
1842                 }
1843                 itau = il + ldwrkl * *m;
1844                 nwork = itau + *m;
1845
1846 /*              Compute A=L*Q */
1847 /*              Workspace: need   M*M [VT] + M*M [L] + M [tau] + M    [work] */
1848 /*              Workspace: prefer M*M [VT] + M*M [L] + M [tau] + M*NB [work] */
1849
1850                 i__1 = *lwork - nwork + 1;
1851                 dgelqf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
1852                         i__1, &ierr);
1853
1854 /*              Copy L to WORK(IL), zeroing about above it */
1855
1856                 dlacpy_("L", m, m, &a[a_offset], lda, &work[il], &ldwrkl);
1857                 i__1 = *m - 1;
1858                 i__2 = *m - 1;
1859                 dlaset_("U", &i__1, &i__2, &c_b63, &c_b63, &work[il + ldwrkl],
1860                          &ldwrkl);
1861
1862 /*              Generate Q in A */
1863 /*              Workspace: need   M*M [VT] + M*M [L] + M [tau] + M    [work] */
1864 /*              Workspace: prefer M*M [VT] + M*M [L] + M [tau] + M*NB [work] */
1865
1866                 i__1 = *lwork - nwork + 1;
1867                 dorglq_(m, n, m, &a[a_offset], lda, &work[itau], &work[nwork],
1868                          &i__1, &ierr);
1869                 ie = itau;
1870                 itauq = ie + *m;
1871                 itaup = itauq + *m;
1872                 nwork = itaup + *m;
1873
1874 /*              Bidiagonalize L in WORK(IL) */
1875 /*              Workspace: need   M*M [VT] + M*M [L] + 3*M [e, tauq, taup] + M      [work] */
1876 /*              Workspace: prefer M*M [VT] + M*M [L] + 3*M [e, tauq, taup] + 2*M*NB [work] */
1877
1878                 i__1 = *lwork - nwork + 1;
1879                 dgebrd_(m, m, &work[il], &ldwrkl, &s[1], &work[ie], &work[
1880                         itauq], &work[itaup], &work[nwork], &i__1, &ierr);
1881
1882 /*              Perform bidiagonal SVD, computing left singular vectors */
1883 /*              of bidiagonal matrix in U, and computing right singular */
1884 /*              vectors of bidiagonal matrix in WORK(IVT) */
1885 /*              Workspace: need   M*M [VT] + M*M [L] + 3*M [e, tauq, taup] + BDSPAC */
1886
1887                 dbdsdc_("U", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &
1888                         work[ivt], m, dum, idum, &work[nwork], &iwork[1], 
1889                         info);
1890
1891 /*              Overwrite U by left singular vectors of L and WORK(IVT) */
1892 /*              by right singular vectors of L */
1893 /*              Workspace: need   M*M [VT] + M*M [L] + 3*M [e, tauq, taup] + M    [work] */
1894 /*              Workspace: prefer M*M [VT] + M*M [L] + 3*M [e, tauq, taup] + M*NB [work] */
1895
1896                 i__1 = *lwork - nwork + 1;
1897                 dormbr_("Q", "L", "N", m, m, m, &work[il], &ldwrkl, &work[
1898                         itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
1899                 i__1 = *lwork - nwork + 1;
1900                 dormbr_("P", "R", "T", m, m, m, &work[il], &ldwrkl, &work[
1901                         itaup], &work[ivt], m, &work[nwork], &i__1, &ierr);
1902
1903 /*              Multiply right singular vectors of L in WORK(IVT) by Q */
1904 /*              in A, storing result in WORK(IL) and copying to A */
1905 /*              Workspace: need   M*M [VT] + M*M [L] */
1906 /*              Workspace: prefer M*M [VT] + M*N [L] */
1907 /*              At this point, L is resized as M by chunk. */
1908
1909                 i__1 = *n;
1910                 i__2 = chunk;
1911                 for (i__ = 1; i__2 < 0 ? i__ >= i__1 : i__ <= i__1; i__ += 
1912                         i__2) {
1913 /* Computing MIN */
1914                     i__3 = *n - i__ + 1;
1915                     blk = f2cmin(i__3,chunk);
1916                     dgemm_("N", "N", m, &blk, m, &c_b84, &work[ivt], m, &a[
1917                             i__ * a_dim1 + 1], lda, &c_b63, &work[il], &
1918                             ldwrkl);
1919                     dlacpy_("F", m, &blk, &work[il], &ldwrkl, &a[i__ * a_dim1 
1920                             + 1], lda);
1921 /* L30: */
1922                 }
1923
1924             } else if (wntqs) {
1925
1926 /*              Path 3t (N >> M, JOBZ='S') */
1927 /*              M right singular vectors to be computed in VT and */
1928 /*              M left singular vectors to be computed in U */
1929
1930                 il = 1;
1931
1932 /*              WORK(IL) is M by M */
1933
1934                 ldwrkl = *m;
1935                 itau = il + ldwrkl * *m;
1936                 nwork = itau + *m;
1937
1938 /*              Compute A=L*Q */
1939 /*              Workspace: need   M*M [L] + M [tau] + M    [work] */
1940 /*              Workspace: prefer M*M [L] + M [tau] + M*NB [work] */
1941
1942                 i__2 = *lwork - nwork + 1;
1943                 dgelqf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
1944                         i__2, &ierr);
1945
1946 /*              Copy L to WORK(IL), zeroing out above it */
1947
1948                 dlacpy_("L", m, m, &a[a_offset], lda, &work[il], &ldwrkl);
1949                 i__2 = *m - 1;
1950                 i__1 = *m - 1;
1951                 dlaset_("U", &i__2, &i__1, &c_b63, &c_b63, &work[il + ldwrkl],
1952                          &ldwrkl);
1953
1954 /*              Generate Q in A */
1955 /*              Workspace: need   M*M [L] + M [tau] + M    [work] */
1956 /*              Workspace: prefer M*M [L] + M [tau] + M*NB [work] */
1957
1958                 i__2 = *lwork - nwork + 1;
1959                 dorglq_(m, n, m, &a[a_offset], lda, &work[itau], &work[nwork],
1960                          &i__2, &ierr);
1961                 ie = itau;
1962                 itauq = ie + *m;
1963                 itaup = itauq + *m;
1964                 nwork = itaup + *m;
1965
1966 /*              Bidiagonalize L in WORK(IU). */
1967 /*              Workspace: need   M*M [L] + 3*M [e, tauq, taup] + M      [work] */
1968 /*              Workspace: prefer M*M [L] + 3*M [e, tauq, taup] + 2*M*NB [work] */
1969
1970                 i__2 = *lwork - nwork + 1;
1971                 dgebrd_(m, m, &work[il], &ldwrkl, &s[1], &work[ie], &work[
1972                         itauq], &work[itaup], &work[nwork], &i__2, &ierr);
1973
1974 /*              Perform bidiagonal SVD, computing left singular vectors */
1975 /*              of bidiagonal matrix in U and computing right singular */
1976 /*              vectors of bidiagonal matrix in VT */
1977 /*              Workspace: need   M*M [L] + 3*M [e, tauq, taup] + BDSPAC */
1978
1979                 dbdsdc_("U", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &vt[
1980                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
1981                         info);
1982
1983 /*              Overwrite U by left singular vectors of L and VT */
1984 /*              by right singular vectors of L */
1985 /*              Workspace: need   M*M [L] + 3*M [e, tauq, taup] + M    [work] */
1986 /*              Workspace: prefer M*M [L] + 3*M [e, tauq, taup] + M*NB [work] */
1987
1988                 i__2 = *lwork - nwork + 1;
1989                 dormbr_("Q", "L", "N", m, m, m, &work[il], &ldwrkl, &work[
1990                         itauq], &u[u_offset], ldu, &work[nwork], &i__2, &ierr);
1991                 i__2 = *lwork - nwork + 1;
1992                 dormbr_("P", "R", "T", m, m, m, &work[il], &ldwrkl, &work[
1993                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__2, &
1994                         ierr);
1995
1996 /*              Multiply right singular vectors of L in WORK(IL) by */
1997 /*              Q in A, storing result in VT */
1998 /*              Workspace: need   M*M [L] */
1999
2000                 dlacpy_("F", m, m, &vt[vt_offset], ldvt, &work[il], &ldwrkl);
2001                 dgemm_("N", "N", m, n, m, &c_b84, &work[il], &ldwrkl, &a[
2002                         a_offset], lda, &c_b63, &vt[vt_offset], ldvt);
2003
2004             } else if (wntqa) {
2005
2006 /*              Path 4t (N >> M, JOBZ='A') */
2007 /*              N right singular vectors to be computed in VT and */
2008 /*              M left singular vectors to be computed in U */
2009
2010                 ivt = 1;
2011
2012 /*              WORK(IVT) is M by M */
2013
2014                 ldwkvt = *m;
2015                 itau = ivt + ldwkvt * *m;
2016                 nwork = itau + *m;
2017
2018 /*              Compute A=L*Q, copying result to VT */
2019 /*              Workspace: need   M*M [VT] + M [tau] + M    [work] */
2020 /*              Workspace: prefer M*M [VT] + M [tau] + M*NB [work] */
2021
2022                 i__2 = *lwork - nwork + 1;
2023                 dgelqf_(m, n, &a[a_offset], lda, &work[itau], &work[nwork], &
2024                         i__2, &ierr);
2025                 dlacpy_("U", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt);
2026
2027 /*              Generate Q in VT */
2028 /*              Workspace: need   M*M [VT] + M [tau] + N    [work] */
2029 /*              Workspace: prefer M*M [VT] + M [tau] + N*NB [work] */
2030
2031                 i__2 = *lwork - nwork + 1;
2032                 dorglq_(n, n, m, &vt[vt_offset], ldvt, &work[itau], &work[
2033                         nwork], &i__2, &ierr);
2034
2035 /*              Produce L in A, zeroing out other entries */
2036
2037                 i__2 = *m - 1;
2038                 i__1 = *m - 1;
2039                 dlaset_("U", &i__2, &i__1, &c_b63, &c_b63, &a[(a_dim1 << 1) + 
2040                         1], lda);
2041                 ie = itau;
2042                 itauq = ie + *m;
2043                 itaup = itauq + *m;
2044                 nwork = itaup + *m;
2045
2046 /*              Bidiagonalize L in A */
2047 /*              Workspace: need   M*M [VT] + 3*M [e, tauq, taup] + M      [work] */
2048 /*              Workspace: prefer M*M [VT] + 3*M [e, tauq, taup] + 2*M*NB [work] */
2049
2050                 i__2 = *lwork - nwork + 1;
2051                 dgebrd_(m, m, &a[a_offset], lda, &s[1], &work[ie], &work[
2052                         itauq], &work[itaup], &work[nwork], &i__2, &ierr);
2053
2054 /*              Perform bidiagonal SVD, computing left singular vectors */
2055 /*              of bidiagonal matrix in U and computing right singular */
2056 /*              vectors of bidiagonal matrix in WORK(IVT) */
2057 /*              Workspace: need   M*M [VT] + 3*M [e, tauq, taup] + BDSPAC */
2058
2059                 dbdsdc_("U", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &
2060                         work[ivt], &ldwkvt, dum, idum, &work[nwork], &iwork[1]
2061                         , info);
2062
2063 /*              Overwrite U by left singular vectors of L and WORK(IVT) */
2064 /*              by right singular vectors of L */
2065 /*              Workspace: need   M*M [VT] + 3*M [e, tauq, taup]+ M    [work] */
2066 /*              Workspace: prefer M*M [VT] + 3*M [e, tauq, taup]+ M*NB [work] */
2067
2068                 i__2 = *lwork - nwork + 1;
2069                 dormbr_("Q", "L", "N", m, m, m, &a[a_offset], lda, &work[
2070                         itauq], &u[u_offset], ldu, &work[nwork], &i__2, &ierr);
2071                 i__2 = *lwork - nwork + 1;
2072                 dormbr_("P", "R", "T", m, m, m, &a[a_offset], lda, &work[
2073                         itaup], &work[ivt], &ldwkvt, &work[nwork], &i__2, &
2074                         ierr);
2075
2076 /*              Multiply right singular vectors of L in WORK(IVT) by */
2077 /*              Q in VT, storing result in A */
2078 /*              Workspace: need   M*M [VT] */
2079
2080                 dgemm_("N", "N", m, n, m, &c_b84, &work[ivt], &ldwkvt, &vt[
2081                         vt_offset], ldvt, &c_b63, &a[a_offset], lda);
2082
2083 /*              Copy right singular vectors of A from A to VT */
2084
2085                 dlacpy_("F", m, n, &a[a_offset], lda, &vt[vt_offset], ldvt);
2086
2087             }
2088
2089         } else {
2090
2091 /*           N .LT. MNTHR */
2092
2093 /*           Path 5t (N > M, but not much larger) */
2094 /*           Reduce to bidiagonal form without LQ decomposition */
2095
2096             ie = 1;
2097             itauq = ie + *m;
2098             itaup = itauq + *m;
2099             nwork = itaup + *m;
2100
2101 /*           Bidiagonalize A */
2102 /*           Workspace: need   3*M [e, tauq, taup] + N        [work] */
2103 /*           Workspace: prefer 3*M [e, tauq, taup] + (M+N)*NB [work] */
2104
2105             i__2 = *lwork - nwork + 1;
2106             dgebrd_(m, n, &a[a_offset], lda, &s[1], &work[ie], &work[itauq], &
2107                     work[itaup], &work[nwork], &i__2, &ierr);
2108             if (wntqn) {
2109
2110 /*              Path 5tn (N > M, JOBZ='N') */
2111 /*              Perform bidiagonal SVD, only computing singular values */
2112 /*              Workspace: need   3*M [e, tauq, taup] + BDSPAC */
2113
2114                 dbdsdc_("L", "N", m, &s[1], &work[ie], dum, &c__1, dum, &c__1,
2115                          dum, idum, &work[nwork], &iwork[1], info);
2116             } else if (wntqo) {
2117 /*              Path 5to (N > M, JOBZ='O') */
2118                 ldwkvt = *m;
2119                 ivt = nwork;
2120                 if (*lwork >= *m * *n + *m * 3 + bdspac) {
2121
2122 /*                 WORK( IVT ) is M by N */
2123
2124                     dlaset_("F", m, n, &c_b63, &c_b63, &work[ivt], &ldwkvt);
2125                     nwork = ivt + ldwkvt * *n;
2126 /*                 IL is unused; silence compile warnings */
2127                     il = -1;
2128                 } else {
2129
2130 /*                 WORK( IVT ) is M by M */
2131
2132                     nwork = ivt + ldwkvt * *m;
2133                     il = nwork;
2134
2135 /*                 WORK(IL) is M by CHUNK */
2136
2137                     chunk = (*lwork - *m * *m - *m * 3) / *m;
2138                 }
2139
2140 /*              Perform bidiagonal SVD, computing left singular vectors */
2141 /*              of bidiagonal matrix in U and computing right singular */
2142 /*              vectors of bidiagonal matrix in WORK(IVT) */
2143 /*              Workspace: need   3*M [e, tauq, taup] + M*M [VT] + BDSPAC */
2144
2145                 dbdsdc_("L", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &
2146                         work[ivt], &ldwkvt, dum, idum, &work[nwork], &iwork[1]
2147                         , info);
2148
2149 /*              Overwrite U by left singular vectors of A */
2150 /*              Workspace: need   3*M [e, tauq, taup] + M*M [VT] + M    [work] */
2151 /*              Workspace: prefer 3*M [e, tauq, taup] + M*M [VT] + M*NB [work] */
2152
2153                 i__2 = *lwork - nwork + 1;
2154                 dormbr_("Q", "L", "N", m, m, n, &a[a_offset], lda, &work[
2155                         itauq], &u[u_offset], ldu, &work[nwork], &i__2, &ierr);
2156
2157                 if (*lwork >= *m * *n + *m * 3 + bdspac) {
2158
2159 /*                 Path 5to-fast */
2160 /*                 Overwrite WORK(IVT) by left singular vectors of A */
2161 /*                 Workspace: need   3*M [e, tauq, taup] + M*N [VT] + M    [work] */
2162 /*                 Workspace: prefer 3*M [e, tauq, taup] + M*N [VT] + M*NB [work] */
2163
2164                     i__2 = *lwork - nwork + 1;
2165                     dormbr_("P", "R", "T", m, n, m, &a[a_offset], lda, &work[
2166                             itaup], &work[ivt], &ldwkvt, &work[nwork], &i__2, 
2167                             &ierr);
2168
2169 /*                 Copy right singular vectors of A from WORK(IVT) to A */
2170
2171                     dlacpy_("F", m, n, &work[ivt], &ldwkvt, &a[a_offset], lda);
2172                 } else {
2173
2174 /*                 Path 5to-slow */
2175 /*                 Generate P**T in A */
2176 /*                 Workspace: need   3*M [e, tauq, taup] + M*M [VT] + M    [work] */
2177 /*                 Workspace: prefer 3*M [e, tauq, taup] + M*M [VT] + M*NB [work] */
2178
2179                     i__2 = *lwork - nwork + 1;
2180                     dorgbr_("P", m, n, m, &a[a_offset], lda, &work[itaup], &
2181                             work[nwork], &i__2, &ierr);
2182
2183 /*                 Multiply Q in A by right singular vectors of */
2184 /*                 bidiagonal matrix in WORK(IVT), storing result in */
2185 /*                 WORK(IL) and copying to A */
2186 /*                 Workspace: need   3*M [e, tauq, taup] + M*M [VT] + M*NB [L] */
2187 /*                 Workspace: prefer 3*M [e, tauq, taup] + M*M [VT] + M*N  [L] */
2188
2189                     i__2 = *n;
2190                     i__1 = chunk;
2191                     for (i__ = 1; i__1 < 0 ? i__ >= i__2 : i__ <= i__2; i__ +=
2192                              i__1) {
2193 /* Computing MIN */
2194                         i__3 = *n - i__ + 1;
2195                         blk = f2cmin(i__3,chunk);
2196                         dgemm_("N", "N", m, &blk, m, &c_b84, &work[ivt], &
2197                                 ldwkvt, &a[i__ * a_dim1 + 1], lda, &c_b63, &
2198                                 work[il], m);
2199                         dlacpy_("F", m, &blk, &work[il], m, &a[i__ * a_dim1 + 
2200                                 1], lda);
2201 /* L40: */
2202                     }
2203                 }
2204             } else if (wntqs) {
2205
2206 /*              Path 5ts (N > M, JOBZ='S') */
2207 /*              Perform bidiagonal SVD, computing left singular vectors */
2208 /*              of bidiagonal matrix in U and computing right singular */
2209 /*              vectors of bidiagonal matrix in VT */
2210 /*              Workspace: need   3*M [e, tauq, taup] + BDSPAC */
2211
2212                 dlaset_("F", m, n, &c_b63, &c_b63, &vt[vt_offset], ldvt);
2213                 dbdsdc_("L", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &vt[
2214                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
2215                         info);
2216
2217 /*              Overwrite U by left singular vectors of A and VT */
2218 /*              by right singular vectors of A */
2219 /*              Workspace: need   3*M [e, tauq, taup] + M    [work] */
2220 /*              Workspace: prefer 3*M [e, tauq, taup] + M*NB [work] */
2221
2222                 i__1 = *lwork - nwork + 1;
2223                 dormbr_("Q", "L", "N", m, m, n, &a[a_offset], lda, &work[
2224                         itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
2225                 i__1 = *lwork - nwork + 1;
2226                 dormbr_("P", "R", "T", m, n, m, &a[a_offset], lda, &work[
2227                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__1, &
2228                         ierr);
2229             } else if (wntqa) {
2230
2231 /*              Path 5ta (N > M, JOBZ='A') */
2232 /*              Perform bidiagonal SVD, computing left singular vectors */
2233 /*              of bidiagonal matrix in U and computing right singular */
2234 /*              vectors of bidiagonal matrix in VT */
2235 /*              Workspace: need   3*M [e, tauq, taup] + BDSPAC */
2236
2237                 dlaset_("F", n, n, &c_b63, &c_b63, &vt[vt_offset], ldvt);
2238                 dbdsdc_("L", "I", m, &s[1], &work[ie], &u[u_offset], ldu, &vt[
2239                         vt_offset], ldvt, dum, idum, &work[nwork], &iwork[1], 
2240                         info);
2241
2242 /*              Set the right corner of VT to identity matrix */
2243
2244                 if (*n > *m) {
2245                     i__1 = *n - *m;
2246                     i__2 = *n - *m;
2247                     dlaset_("F", &i__1, &i__2, &c_b63, &c_b84, &vt[*m + 1 + (*
2248                             m + 1) * vt_dim1], ldvt);
2249                 }
2250
2251 /*              Overwrite U by left singular vectors of A and VT */
2252 /*              by right singular vectors of A */
2253 /*              Workspace: need   3*M [e, tauq, taup] + N    [work] */
2254 /*              Workspace: prefer 3*M [e, tauq, taup] + N*NB [work] */
2255
2256                 i__1 = *lwork - nwork + 1;
2257                 dormbr_("Q", "L", "N", m, m, n, &a[a_offset], lda, &work[
2258                         itauq], &u[u_offset], ldu, &work[nwork], &i__1, &ierr);
2259                 i__1 = *lwork - nwork + 1;
2260                 dormbr_("P", "R", "T", n, n, m, &a[a_offset], lda, &work[
2261                         itaup], &vt[vt_offset], ldvt, &work[nwork], &i__1, &
2262                         ierr);
2263             }
2264
2265         }
2266
2267     }
2268
2269 /*     Undo scaling if necessary */
2270
2271     if (iscl == 1) {
2272         if (anrm > bignum) {
2273             dlascl_("G", &c__0, &c__0, &bignum, &anrm, &minmn, &c__1, &s[1], &
2274                     minmn, &ierr);
2275         }
2276         if (anrm < smlnum) {
2277             dlascl_("G", &c__0, &c__0, &smlnum, &anrm, &minmn, &c__1, &s[1], &
2278                     minmn, &ierr);
2279         }
2280     }
2281
2282 /*     Return optimal workspace in WORK(1) */
2283
2284     work[1] = (doublereal) maxwrk;
2285
2286     return 0;
2287
2288 /*     End of DGESDD */
2289
2290 } /* dgesdd_ */
2291