3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download CGESDD + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cgesdd.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/cgesdd.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cgesdd.f">
21 * SUBROUTINE CGESDD( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT,
22 * WORK, LWORK, RWORK, IWORK, INFO )
24 * .. Scalar Arguments ..
26 * INTEGER INFO, LDA, LDU, LDVT, LWORK, M, N
28 * .. Array Arguments ..
30 * REAL RWORK( * ), S( * )
31 * COMPLEX A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
41 *> CGESDD computes the singular value decomposition (SVD) of a complex
42 *> M-by-N matrix A, optionally computing the left and/or right singular
43 *> vectors, by using divide-and-conquer method. The SVD is written
45 *> A = U * SIGMA * conjugate-transpose(V)
47 *> where SIGMA is an M-by-N matrix which is zero except for its
48 *> min(m,n) diagonal elements, U is an M-by-M unitary matrix, and
49 *> V is an N-by-N unitary matrix. The diagonal elements of SIGMA
50 *> are the singular values of A; they are real and non-negative, and
51 *> are returned in descending order. The first min(m,n) columns of
52 *> U and V are the left and right singular vectors of A.
54 *> Note that the routine returns VT = V**H, not V.
56 *> The divide and conquer algorithm makes very mild assumptions about
57 *> floating point arithmetic. It will work on machines with a guard
58 *> digit in add/subtract, or on those binary machines without guard
59 *> digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or
60 *> Cray-2. It could conceivably fail on hexadecimal or decimal machines
61 *> without guard digits, but we know of none.
69 *> JOBZ is CHARACTER*1
70 *> Specifies options for computing all or part of the matrix U:
71 *> = 'A': all M columns of U and all N rows of V**H are
72 *> returned in the arrays U and VT;
73 *> = 'S': the first min(M,N) columns of U and the first
74 *> min(M,N) rows of V**H are returned in the arrays U
76 *> = 'O': If M >= N, the first N columns of U are overwritten
77 *> in the array A and all rows of V**H are returned in
79 *> otherwise, all columns of U are returned in the
80 *> array U and the first M rows of V**H are overwritten
82 *> = 'N': no columns of U or rows of V**H are computed.
88 *> The number of rows of the input matrix A. M >= 0.
94 *> The number of columns of the input matrix A. N >= 0.
99 *> A is COMPLEX array, dimension (LDA,N)
100 *> On entry, the M-by-N matrix A.
102 *> if JOBZ = 'O', A is overwritten with the first N columns
103 *> of U (the left singular vectors, stored
104 *> columnwise) if M >= N;
105 *> A is overwritten with the first M rows
106 *> of V**H (the right singular vectors, stored
107 *> rowwise) otherwise.
108 *> if JOBZ .ne. 'O', the contents of A are destroyed.
114 *> The leading dimension of the array A. LDA >= max(1,M).
119 *> S is REAL array, dimension (min(M,N))
120 *> The singular values of A, sorted so that S(i) >= S(i+1).
125 *> U is COMPLEX array, dimension (LDU,UCOL)
126 *> UCOL = M if JOBZ = 'A' or JOBZ = 'O' and M < N;
127 *> UCOL = min(M,N) if JOBZ = 'S'.
128 *> If JOBZ = 'A' or JOBZ = 'O' and M < N, U contains the M-by-M
130 *> if JOBZ = 'S', U contains the first min(M,N) columns of U
131 *> (the left singular vectors, stored columnwise);
132 *> if JOBZ = 'O' and M >= N, or JOBZ = 'N', U is not referenced.
138 *> The leading dimension of the array U. LDU >= 1;
139 *> if JOBZ = 'S' or 'A' or JOBZ = 'O' and M < N, LDU >= M.
144 *> VT is COMPLEX array, dimension (LDVT,N)
145 *> If JOBZ = 'A' or JOBZ = 'O' and M >= N, VT contains the
146 *> N-by-N unitary matrix V**H;
147 *> if JOBZ = 'S', VT contains the first min(M,N) rows of
148 *> V**H (the right singular vectors, stored rowwise);
149 *> if JOBZ = 'O' and M < N, or JOBZ = 'N', VT is not referenced.
155 *> The leading dimension of the array VT. LDVT >= 1;
156 *> if JOBZ = 'A' or JOBZ = 'O' and M >= N, LDVT >= N;
157 *> if JOBZ = 'S', LDVT >= min(M,N).
162 *> WORK is COMPLEX array, dimension (MAX(1,LWORK))
163 *> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
169 *> The dimension of the array WORK. LWORK >= 1.
170 *> If LWORK = -1, a workspace query is assumed. The optimal
171 *> size for the WORK array is calculated and stored in WORK(1),
172 *> and no other work except argument checking is performed.
174 *> Let mx = max(M,N) and mn = min(M,N).
175 *> If JOBZ = 'N', LWORK >= 2*mn + mx.
176 *> If JOBZ = 'O', LWORK >= 2*mn*mn + 2*mn + mx.
177 *> If JOBZ = 'S', LWORK >= mn*mn + 3*mn.
178 *> If JOBZ = 'A', LWORK >= mn*mn + 2*mn + mx.
179 *> These are not tight minimums in all cases; see comments inside code.
180 *> For good performance, LWORK should generally be larger;
181 *> a query is recommended.
186 *> RWORK is REAL array, dimension (MAX(1,LRWORK))
187 *> Let mx = max(M,N) and mn = min(M,N).
188 *> If JOBZ = 'N', LRWORK >= 5*mn (LAPACK <= 3.6 needs 7*mn);
189 *> else if mx >> mn, LRWORK >= 5*mn*mn + 5*mn;
190 *> else LRWORK >= max( 5*mn*mn + 5*mn,
191 *> 2*mx*mn + 2*mn*mn + mn ).
196 *> IWORK is INTEGER array, dimension (8*min(M,N))
202 *> = 0: successful exit.
203 *> < 0: if INFO = -i, the i-th argument had an illegal value.
204 *> > 0: The updating process of SBDSDC did not converge.
210 *> \author Univ. of Tennessee
211 *> \author Univ. of California Berkeley
212 *> \author Univ. of Colorado Denver
217 *> \ingroup complexGEsing
219 *> \par Contributors:
222 *> Ming Gu and Huan Ren, Computer Science Division, University of
223 *> California at Berkeley, USA
225 * =====================================================================
226 SUBROUTINE CGESDD( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT,
227 $ WORK, LWORK, RWORK, IWORK, INFO )
230 * -- LAPACK driver routine (version 3.6.1) --
231 * -- LAPACK is a software package provided by Univ. of Tennessee, --
232 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
235 * .. Scalar Arguments ..
237 INTEGER INFO, LDA, LDU, LDVT, LWORK, M, N
239 * .. Array Arguments ..
241 REAL RWORK( * ), S( * )
242 COMPLEX A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
246 * =====================================================================
250 PARAMETER ( CZERO = ( 0.0E+0, 0.0E+0 ),
251 $ CONE = ( 1.0E+0, 0.0E+0 ) )
253 PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0 )
255 * .. Local Scalars ..
256 LOGICAL LQUERY, WNTQA, WNTQAS, WNTQN, WNTQO, WNTQS
257 INTEGER BLK, CHUNK, I, IE, IERR, IL, IR, IRU, IRVT,
258 $ ISCL, ITAU, ITAUP, ITAUQ, IU, IVT, LDWKVT,
259 $ LDWRKL, LDWRKR, LDWRKU, MAXWRK, MINMN, MINWRK,
260 $ MNTHR1, MNTHR2, NRWORK, NWORK, WRKBL
261 INTEGER LWORK_CGEBRD_MN, LWORK_CGEBRD_MM,
262 $ LWORK_CGEBRD_NN, LWORK_CGELQF_MN,
264 $ LWORK_CUNGBR_P_MN, LWORK_CUNGBR_P_NN,
265 $ LWORK_CUNGBR_Q_MN, LWORK_CUNGBR_Q_MM,
266 $ LWORK_CUNGLQ_MN, LWORK_CUNGLQ_NN,
267 $ LWORK_CUNGQR_MM, LWORK_CUNGQR_MN,
268 $ LWORK_CUNMBR_PRC_MM, LWORK_CUNMBR_QLN_MM,
269 $ LWORK_CUNMBR_PRC_MN, LWORK_CUNMBR_QLN_MN,
270 $ LWORK_CUNMBR_PRC_NN, LWORK_CUNMBR_QLN_NN
271 REAL ANRM, BIGNUM, EPS, SMLNUM
278 * .. External Subroutines ..
279 EXTERNAL CGEBRD, CGELQF, CGEMM, CGEQRF, CLACP2, CLACPY,
280 $ CLACRM, CLARCM, CLASCL, CLASET, CUNGBR, CUNGLQ,
281 $ CUNGQR, CUNMBR, SBDSDC, SLASCL, XERBLA
283 * .. External Functions ..
286 EXTERNAL LSAME, SLAMCH, CLANGE
288 * .. Intrinsic Functions ..
289 INTRINSIC INT, MAX, MIN, SQRT
291 * .. Executable Statements ..
293 * Test the input arguments
297 MNTHR1 = INT( MINMN*17.0E0 / 9.0E0 )
298 MNTHR2 = INT( MINMN*5.0E0 / 3.0E0 )
299 WNTQA = LSAME( JOBZ, 'A' )
300 WNTQS = LSAME( JOBZ, 'S' )
301 WNTQAS = WNTQA .OR. WNTQS
302 WNTQO = LSAME( JOBZ, 'O' )
303 WNTQN = LSAME( JOBZ, 'N' )
304 LQUERY = ( LWORK.EQ.-1 )
308 IF( .NOT.( WNTQA .OR. WNTQS .OR. WNTQO .OR. WNTQN ) ) THEN
310 ELSE IF( M.LT.0 ) THEN
312 ELSE IF( N.LT.0 ) THEN
314 ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
316 ELSE IF( LDU.LT.1 .OR. ( WNTQAS .AND. LDU.LT.M ) .OR.
317 $ ( WNTQO .AND. M.LT.N .AND. LDU.LT.M ) ) THEN
319 ELSE IF( LDVT.LT.1 .OR. ( WNTQA .AND. LDVT.LT.N ) .OR.
320 $ ( WNTQS .AND. LDVT.LT.MINMN ) .OR.
321 $ ( WNTQO .AND. M.GE.N .AND. LDVT.LT.N ) ) THEN
326 * Note: Comments in the code beginning "Workspace:" describe the
327 * minimal amount of workspace allocated at that point in the code,
328 * as well as the preferred amount for good performance.
329 * CWorkspace refers to complex workspace, and RWorkspace to
330 * real workspace. NB refers to the optimal block size for the
331 * immediately following subroutine, as returned by ILAENV.)
333 IF( INFO.EQ.0 .AND. M.GT.0 .AND. N.GT.0 ) THEN
336 * There is no complex work space needed for bidiagonal SVD
337 * The real work space needed for bidiagonal SVD (sbdsdc) is
338 * BDSPAC = 3*N*N + 4*N for singular values and vectors;
339 * BDSPAC = 4*N for singular values only;
340 * not including e, RU, and RVT matrices.
342 * Compute space preferred for each routine
343 CALL CGEBRD( M, N, CDUM(1), M, DUM(1), DUM(1), CDUM(1),
344 $ CDUM(1), CDUM(1), -1, IERR )
345 LWORK_CGEBRD_MN = INT( CDUM(1) )
347 CALL CGEBRD( N, N, CDUM(1), N, DUM(1), DUM(1), CDUM(1),
348 $ CDUM(1), CDUM(1), -1, IERR )
349 LWORK_CGEBRD_NN = INT( CDUM(1) )
351 CALL CGEQRF( M, N, CDUM(1), M, CDUM(1), CDUM(1), -1, IERR )
352 LWORK_CGEQRF_MN = INT( CDUM(1) )
354 CALL CUNGBR( 'P', N, N, N, CDUM(1), N, CDUM(1), CDUM(1),
356 LWORK_CUNGBR_P_NN = INT( CDUM(1) )
358 CALL CUNGBR( 'Q', M, M, N, CDUM(1), M, CDUM(1), CDUM(1),
360 LWORK_CUNGBR_Q_MM = INT( CDUM(1) )
362 CALL CUNGBR( 'Q', M, N, N, CDUM(1), M, CDUM(1), CDUM(1),
364 LWORK_CUNGBR_Q_MN = INT( CDUM(1) )
366 CALL CUNGQR( M, M, N, CDUM(1), M, CDUM(1), CDUM(1),
368 LWORK_CUNGQR_MM = INT( CDUM(1) )
370 CALL CUNGQR( M, N, N, CDUM(1), M, CDUM(1), CDUM(1),
372 LWORK_CUNGQR_MN = INT( CDUM(1) )
374 CALL CUNMBR( 'P', 'R', 'C', N, N, N, CDUM(1), N, CDUM(1),
375 $ CDUM(1), N, CDUM(1), -1, IERR )
376 LWORK_CUNMBR_PRC_NN = INT( CDUM(1) )
378 CALL CUNMBR( 'Q', 'L', 'N', M, M, N, CDUM(1), M, CDUM(1),
379 $ CDUM(1), M, CDUM(1), -1, IERR )
380 LWORK_CUNMBR_QLN_MM = INT( CDUM(1) )
382 CALL CUNMBR( 'Q', 'L', 'N', M, N, N, CDUM(1), M, CDUM(1),
383 $ CDUM(1), M, CDUM(1), -1, IERR )
384 LWORK_CUNMBR_QLN_MN = INT( CDUM(1) )
386 CALL CUNMBR( 'Q', 'L', 'N', N, N, N, CDUM(1), N, CDUM(1),
387 $ CDUM(1), N, CDUM(1), -1, IERR )
388 LWORK_CUNMBR_QLN_NN = INT( CDUM(1) )
390 IF( M.GE.MNTHR1 ) THEN
393 * Path 1 (M >> N, JOBZ='N')
395 MAXWRK = N + LWORK_CGEQRF_MN
396 MAXWRK = MAX( MAXWRK, 2*N + LWORK_CGEBRD_NN )
398 ELSE IF( WNTQO ) THEN
400 * Path 2 (M >> N, JOBZ='O')
402 WRKBL = N + LWORK_CGEQRF_MN
403 WRKBL = MAX( WRKBL, N + LWORK_CUNGQR_MN )
404 WRKBL = MAX( WRKBL, 2*N + LWORK_CGEBRD_NN )
405 WRKBL = MAX( WRKBL, 2*N + LWORK_CUNMBR_QLN_NN )
406 WRKBL = MAX( WRKBL, 2*N + LWORK_CUNMBR_PRC_NN )
407 MAXWRK = M*N + N*N + WRKBL
409 ELSE IF( WNTQS ) THEN
411 * Path 3 (M >> N, JOBZ='S')
413 WRKBL = N + LWORK_CGEQRF_MN
414 WRKBL = MAX( WRKBL, N + LWORK_CUNGQR_MN )
415 WRKBL = MAX( WRKBL, 2*N + LWORK_CGEBRD_NN )
416 WRKBL = MAX( WRKBL, 2*N + LWORK_CUNMBR_QLN_NN )
417 WRKBL = MAX( WRKBL, 2*N + LWORK_CUNMBR_PRC_NN )
420 ELSE IF( WNTQA ) THEN
422 * Path 4 (M >> N, JOBZ='A')
424 WRKBL = N + LWORK_CGEQRF_MN
425 WRKBL = MAX( WRKBL, N + LWORK_CUNGQR_MM )
426 WRKBL = MAX( WRKBL, 2*N + LWORK_CGEBRD_NN )
427 WRKBL = MAX( WRKBL, 2*N + LWORK_CUNMBR_QLN_NN )
428 WRKBL = MAX( WRKBL, 2*N + LWORK_CUNMBR_PRC_NN )
430 MINWRK = N*N + MAX( 3*N, N + M )
432 ELSE IF( M.GE.MNTHR2 ) THEN
434 * Path 5 (M >> N, but not as much as MNTHR1)
436 MAXWRK = 2*N + LWORK_CGEBRD_MN
439 * Path 5o (M >> N, JOBZ='O')
440 MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNGBR_P_NN )
441 MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNGBR_Q_MN )
442 MAXWRK = MAXWRK + M*N
443 MINWRK = MINWRK + N*N
444 ELSE IF( WNTQS ) THEN
445 * Path 5s (M >> N, JOBZ='S')
446 MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNGBR_P_NN )
447 MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNGBR_Q_MN )
448 ELSE IF( WNTQA ) THEN
449 * Path 5a (M >> N, JOBZ='A')
450 MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNGBR_P_NN )
451 MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNGBR_Q_MM )
455 * Path 6 (M >= N, but not much larger)
457 MAXWRK = 2*N + LWORK_CGEBRD_MN
460 * Path 6o (M >= N, JOBZ='O')
461 MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNMBR_PRC_NN )
462 MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNMBR_QLN_MN )
463 MAXWRK = MAXWRK + M*N
464 MINWRK = MINWRK + N*N
465 ELSE IF( WNTQS ) THEN
466 * Path 6s (M >= N, JOBZ='S')
467 MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNMBR_QLN_MN )
468 MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNMBR_PRC_NN )
469 ELSE IF( WNTQA ) THEN
470 * Path 6a (M >= N, JOBZ='A')
471 MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNMBR_QLN_MM )
472 MAXWRK = MAX( MAXWRK, 2*N + LWORK_CUNMBR_PRC_NN )
477 * There is no complex work space needed for bidiagonal SVD
478 * The real work space needed for bidiagonal SVD (sbdsdc) is
479 * BDSPAC = 3*M*M + 4*M for singular values and vectors;
480 * BDSPAC = 4*M for singular values only;
481 * not including e, RU, and RVT matrices.
483 * Compute space preferred for each routine
484 CALL CGEBRD( M, N, CDUM(1), M, DUM(1), DUM(1), CDUM(1),
485 $ CDUM(1), CDUM(1), -1, IERR )
486 LWORK_CGEBRD_MN = INT( CDUM(1) )
488 CALL CGEBRD( M, M, CDUM(1), M, DUM(1), DUM(1), CDUM(1),
489 $ CDUM(1), CDUM(1), -1, IERR )
490 LWORK_CGEBRD_MM = INT( CDUM(1) )
492 CALL CGELQF( M, N, CDUM(1), M, CDUM(1), CDUM(1), -1, IERR )
493 LWORK_CGELQF_MN = INT( CDUM(1) )
495 CALL CUNGBR( 'P', M, N, M, CDUM(1), M, CDUM(1), CDUM(1),
497 LWORK_CUNGBR_P_MN = INT( CDUM(1) )
499 CALL CUNGBR( 'P', N, N, M, CDUM(1), N, CDUM(1), CDUM(1),
501 LWORK_CUNGBR_P_NN = INT( CDUM(1) )
503 CALL CUNGBR( 'Q', M, M, N, CDUM(1), M, CDUM(1), CDUM(1),
505 LWORK_CUNGBR_Q_MM = INT( CDUM(1) )
507 CALL CUNGLQ( M, N, M, CDUM(1), M, CDUM(1), CDUM(1),
509 LWORK_CUNGLQ_MN = INT( CDUM(1) )
511 CALL CUNGLQ( N, N, M, CDUM(1), N, CDUM(1), CDUM(1),
513 LWORK_CUNGLQ_NN = INT( CDUM(1) )
515 CALL CUNMBR( 'P', 'R', 'C', M, M, M, CDUM(1), M, CDUM(1),
516 $ CDUM(1), M, CDUM(1), -1, IERR )
517 LWORK_CUNMBR_PRC_MM = INT( CDUM(1) )
519 CALL CUNMBR( 'P', 'R', 'C', M, N, M, CDUM(1), M, CDUM(1),
520 $ CDUM(1), M, CDUM(1), -1, IERR )
521 LWORK_CUNMBR_PRC_MN = INT( CDUM(1) )
523 CALL CUNMBR( 'P', 'R', 'C', N, N, M, CDUM(1), N, CDUM(1),
524 $ CDUM(1), N, CDUM(1), -1, IERR )
525 LWORK_CUNMBR_PRC_NN = INT( CDUM(1) )
527 CALL CUNMBR( 'Q', 'L', 'N', M, M, M, CDUM(1), M, CDUM(1),
528 $ CDUM(1), M, CDUM(1), -1, IERR )
529 LWORK_CUNMBR_QLN_MM = INT( CDUM(1) )
531 IF( N.GE.MNTHR1 ) THEN
534 * Path 1t (N >> M, JOBZ='N')
536 MAXWRK = M + LWORK_CGELQF_MN
537 MAXWRK = MAX( MAXWRK, 2*M + LWORK_CGEBRD_MM )
539 ELSE IF( WNTQO ) THEN
541 * Path 2t (N >> M, JOBZ='O')
543 WRKBL = M + LWORK_CGELQF_MN
544 WRKBL = MAX( WRKBL, M + LWORK_CUNGLQ_MN )
545 WRKBL = MAX( WRKBL, 2*M + LWORK_CGEBRD_MM )
546 WRKBL = MAX( WRKBL, 2*M + LWORK_CUNMBR_QLN_MM )
547 WRKBL = MAX( WRKBL, 2*M + LWORK_CUNMBR_PRC_MM )
548 MAXWRK = M*N + M*M + WRKBL
550 ELSE IF( WNTQS ) THEN
552 * Path 3t (N >> M, JOBZ='S')
554 WRKBL = M + LWORK_CGELQF_MN
555 WRKBL = MAX( WRKBL, M + LWORK_CUNGLQ_MN )
556 WRKBL = MAX( WRKBL, 2*M + LWORK_CGEBRD_MM )
557 WRKBL = MAX( WRKBL, 2*M + LWORK_CUNMBR_QLN_MM )
558 WRKBL = MAX( WRKBL, 2*M + LWORK_CUNMBR_PRC_MM )
561 ELSE IF( WNTQA ) THEN
563 * Path 4t (N >> M, JOBZ='A')
565 WRKBL = M + LWORK_CGELQF_MN
566 WRKBL = MAX( WRKBL, M + LWORK_CUNGLQ_NN )
567 WRKBL = MAX( WRKBL, 2*M + LWORK_CGEBRD_MM )
568 WRKBL = MAX( WRKBL, 2*M + LWORK_CUNMBR_QLN_MM )
569 WRKBL = MAX( WRKBL, 2*M + LWORK_CUNMBR_PRC_MM )
571 MINWRK = M*M + MAX( 3*M, M + N )
573 ELSE IF( N.GE.MNTHR2 ) THEN
575 * Path 5t (N >> M, but not as much as MNTHR1)
577 MAXWRK = 2*M + LWORK_CGEBRD_MN
580 * Path 5to (N >> M, JOBZ='O')
581 MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNGBR_Q_MM )
582 MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNGBR_P_MN )
583 MAXWRK = MAXWRK + M*N
584 MINWRK = MINWRK + M*M
585 ELSE IF( WNTQS ) THEN
586 * Path 5ts (N >> M, JOBZ='S')
587 MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNGBR_Q_MM )
588 MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNGBR_P_MN )
589 ELSE IF( WNTQA ) THEN
590 * Path 5ta (N >> M, JOBZ='A')
591 MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNGBR_Q_MM )
592 MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNGBR_P_NN )
596 * Path 6t (N > M, but not much larger)
598 MAXWRK = 2*M + LWORK_CGEBRD_MN
601 * Path 6to (N > M, JOBZ='O')
602 MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNMBR_QLN_MM )
603 MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNMBR_PRC_MN )
604 MAXWRK = MAXWRK + M*N
605 MINWRK = MINWRK + M*M
606 ELSE IF( WNTQS ) THEN
607 * Path 6ts (N > M, JOBZ='S')
608 MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNMBR_QLN_MM )
609 MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNMBR_PRC_MN )
610 ELSE IF( WNTQA ) THEN
611 * Path 6ta (N > M, JOBZ='A')
612 MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNMBR_QLN_MM )
613 MAXWRK = MAX( MAXWRK, 2*M + LWORK_CUNMBR_PRC_NN )
617 MAXWRK = MAX( MAXWRK, MINWRK )
621 IF( LWORK.LT.MINWRK .AND. .NOT. LQUERY ) THEN
627 CALL XERBLA( 'CGESDD', -INFO )
629 ELSE IF( LQUERY ) THEN
633 * Quick return if possible
635 IF( M.EQ.0 .OR. N.EQ.0 ) THEN
639 * Get machine constants
642 SMLNUM = SQRT( SLAMCH( 'S' ) ) / EPS
643 BIGNUM = ONE / SMLNUM
645 * Scale A if max element outside range [SMLNUM,BIGNUM]
647 ANRM = CLANGE( 'M', M, N, A, LDA, DUM )
649 IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
651 CALL CLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, IERR )
652 ELSE IF( ANRM.GT.BIGNUM ) THEN
654 CALL CLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, IERR )
659 * A has at least as many rows as columns. If A has sufficiently
660 * more rows than columns, first reduce using the QR
661 * decomposition (if sufficient workspace available)
663 IF( M.GE.MNTHR1 ) THEN
667 * Path 1 (M >> N, JOBZ='N')
668 * No singular vectors to be computed
674 * CWorkspace: need N [tau] + N [work]
675 * CWorkspace: prefer N [tau] + N*NB [work]
678 CALL CGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
679 $ LWORK-NWORK+1, IERR )
683 CALL CLASET( 'L', N-1, N-1, CZERO, CZERO, A( 2, 1 ),
690 * Bidiagonalize R in A
691 * CWorkspace: need 2*N [tauq, taup] + N [work]
692 * CWorkspace: prefer 2*N [tauq, taup] + 2*N*NB [work]
693 * RWorkspace: need N [e]
695 CALL CGEBRD( N, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
696 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
700 * Perform bidiagonal SVD, compute singular values only
702 * RWorkspace: need N [e] + BDSPAC
704 CALL SBDSDC( 'U', 'N', N, S, RWORK( IE ), DUM,1,DUM,1,
705 $ DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
707 ELSE IF( WNTQO ) THEN
709 * Path 2 (M >> N, JOBZ='O')
710 * N left singular vectors to be overwritten on A and
711 * N right singular vectors to be computed in VT
719 IF( LWORK .GE. M*N + N*N + 3*N ) THEN
725 LDWRKR = ( LWORK - N*N - 3*N ) / N
731 * CWorkspace: need N*N [U] + N*N [R] + N [tau] + N [work]
732 * CWorkspace: prefer N*N [U] + N*N [R] + N [tau] + N*NB [work]
735 CALL CGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
736 $ LWORK-NWORK+1, IERR )
738 * Copy R to WORK( IR ), zeroing out below it
740 CALL CLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )
741 CALL CLASET( 'L', N-1, N-1, CZERO, CZERO, WORK( IR+1 ),
745 * CWorkspace: need N*N [U] + N*N [R] + N [tau] + N [work]
746 * CWorkspace: prefer N*N [U] + N*N [R] + N [tau] + N*NB [work]
749 CALL CUNGQR( M, N, N, A, LDA, WORK( ITAU ),
750 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
756 * Bidiagonalize R in WORK(IR)
757 * CWorkspace: need N*N [U] + N*N [R] + 2*N [tauq, taup] + N [work]
758 * CWorkspace: prefer N*N [U] + N*N [R] + 2*N [tauq, taup] + 2*N*NB [work]
759 * RWorkspace: need N [e]
761 CALL CGEBRD( N, N, WORK( IR ), LDWRKR, S, RWORK( IE ),
762 $ WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
763 $ LWORK-NWORK+1, IERR )
765 * Perform bidiagonal SVD, computing left singular vectors
766 * of R in WORK(IRU) and computing right singular vectors
769 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT] + BDSPAC
774 CALL SBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
775 $ N, RWORK( IRVT ), N, DUM, IDUM,
776 $ RWORK( NRWORK ), IWORK, INFO )
778 * Copy real matrix RWORK(IRU) to complex matrix WORK(IU)
779 * Overwrite WORK(IU) by the left singular vectors of R
780 * CWorkspace: need N*N [U] + N*N [R] + 2*N [tauq, taup] + N [work]
781 * CWorkspace: prefer N*N [U] + N*N [R] + 2*N [tauq, taup] + N*NB [work]
784 CALL CLACP2( 'F', N, N, RWORK( IRU ), N, WORK( IU ),
786 CALL CUNMBR( 'Q', 'L', 'N', N, N, N, WORK( IR ), LDWRKR,
787 $ WORK( ITAUQ ), WORK( IU ), LDWRKU,
788 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
790 * Copy real matrix RWORK(IRVT) to complex matrix VT
791 * Overwrite VT by the right singular vectors of R
792 * CWorkspace: need N*N [U] + N*N [R] + 2*N [tauq, taup] + N [work]
793 * CWorkspace: prefer N*N [U] + N*N [R] + 2*N [tauq, taup] + N*NB [work]
796 CALL CLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
797 CALL CUNMBR( 'P', 'R', 'C', N, N, N, WORK( IR ), LDWRKR,
798 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
799 $ LWORK-NWORK+1, IERR )
801 * Multiply Q in A by left singular vectors of R in
802 * WORK(IU), storing result in WORK(IR) and copying to A
803 * CWorkspace: need N*N [U] + N*N [R]
804 * CWorkspace: prefer N*N [U] + M*N [R]
807 DO 10 I = 1, M, LDWRKR
808 CHUNK = MIN( M-I+1, LDWRKR )
809 CALL CGEMM( 'N', 'N', CHUNK, N, N, CONE, A( I, 1 ),
810 $ LDA, WORK( IU ), LDWRKU, CZERO,
811 $ WORK( IR ), LDWRKR )
812 CALL CLACPY( 'F', CHUNK, N, WORK( IR ), LDWRKR,
816 ELSE IF( WNTQS ) THEN
818 * Path 3 (M >> N, JOBZ='S')
819 * N left singular vectors to be computed in U and
820 * N right singular vectors to be computed in VT
831 * CWorkspace: need N*N [R] + N [tau] + N [work]
832 * CWorkspace: prefer N*N [R] + N [tau] + N*NB [work]
835 CALL CGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
836 $ LWORK-NWORK+1, IERR )
838 * Copy R to WORK(IR), zeroing out below it
840 CALL CLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )
841 CALL CLASET( 'L', N-1, N-1, CZERO, CZERO, WORK( IR+1 ),
845 * CWorkspace: need N*N [R] + N [tau] + N [work]
846 * CWorkspace: prefer N*N [R] + N [tau] + N*NB [work]
849 CALL CUNGQR( M, N, N, A, LDA, WORK( ITAU ),
850 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
856 * Bidiagonalize R in WORK(IR)
857 * CWorkspace: need N*N [R] + 2*N [tauq, taup] + N [work]
858 * CWorkspace: prefer N*N [R] + 2*N [tauq, taup] + 2*N*NB [work]
859 * RWorkspace: need N [e]
861 CALL CGEBRD( N, N, WORK( IR ), LDWRKR, S, RWORK( IE ),
862 $ WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
863 $ LWORK-NWORK+1, IERR )
865 * Perform bidiagonal SVD, computing left singular vectors
866 * of bidiagonal matrix in RWORK(IRU) and computing right
867 * singular vectors of bidiagonal matrix in RWORK(IRVT)
869 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT] + BDSPAC
874 CALL SBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
875 $ N, RWORK( IRVT ), N, DUM, IDUM,
876 $ RWORK( NRWORK ), IWORK, INFO )
878 * Copy real matrix RWORK(IRU) to complex matrix U
879 * Overwrite U by left singular vectors of R
880 * CWorkspace: need N*N [R] + 2*N [tauq, taup] + N [work]
881 * CWorkspace: prefer N*N [R] + 2*N [tauq, taup] + N*NB [work]
884 CALL CLACP2( 'F', N, N, RWORK( IRU ), N, U, LDU )
885 CALL CUNMBR( 'Q', 'L', 'N', N, N, N, WORK( IR ), LDWRKR,
886 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
887 $ LWORK-NWORK+1, IERR )
889 * Copy real matrix RWORK(IRVT) to complex matrix VT
890 * Overwrite VT by right singular vectors of R
891 * CWorkspace: need N*N [R] + 2*N [tauq, taup] + N [work]
892 * CWorkspace: prefer N*N [R] + 2*N [tauq, taup] + N*NB [work]
895 CALL CLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
896 CALL CUNMBR( 'P', 'R', 'C', N, N, N, WORK( IR ), LDWRKR,
897 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
898 $ LWORK-NWORK+1, IERR )
900 * Multiply Q in A by left singular vectors of R in
901 * WORK(IR), storing result in U
902 * CWorkspace: need N*N [R]
905 CALL CLACPY( 'F', N, N, U, LDU, WORK( IR ), LDWRKR )
906 CALL CGEMM( 'N', 'N', M, N, N, CONE, A, LDA, WORK( IR ),
907 $ LDWRKR, CZERO, U, LDU )
909 ELSE IF( WNTQA ) THEN
911 * Path 4 (M >> N, JOBZ='A')
912 * M left singular vectors to be computed in U and
913 * N right singular vectors to be computed in VT
923 * Compute A=Q*R, copying result to U
924 * CWorkspace: need N*N [U] + N [tau] + N [work]
925 * CWorkspace: prefer N*N [U] + N [tau] + N*NB [work]
928 CALL CGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
929 $ LWORK-NWORK+1, IERR )
930 CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
933 * CWorkspace: need N*N [U] + N [tau] + M [work]
934 * CWorkspace: prefer N*N [U] + N [tau] + M*NB [work]
937 CALL CUNGQR( M, M, N, U, LDU, WORK( ITAU ),
938 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
940 * Produce R in A, zeroing out below it
942 CALL CLASET( 'L', N-1, N-1, CZERO, CZERO, A( 2, 1 ),
949 * Bidiagonalize R in A
950 * CWorkspace: need N*N [U] + 2*N [tauq, taup] + N [work]
951 * CWorkspace: prefer N*N [U] + 2*N [tauq, taup] + 2*N*NB [work]
952 * RWorkspace: need N [e]
954 CALL CGEBRD( N, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
955 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
961 * Perform bidiagonal SVD, computing left singular vectors
962 * of bidiagonal matrix in RWORK(IRU) and computing right
963 * singular vectors of bidiagonal matrix in RWORK(IRVT)
965 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT] + BDSPAC
967 CALL SBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
968 $ N, RWORK( IRVT ), N, DUM, IDUM,
969 $ RWORK( NRWORK ), IWORK, INFO )
971 * Copy real matrix RWORK(IRU) to complex matrix WORK(IU)
972 * Overwrite WORK(IU) by left singular vectors of R
973 * CWorkspace: need N*N [U] + 2*N [tauq, taup] + N [work]
974 * CWorkspace: prefer N*N [U] + 2*N [tauq, taup] + N*NB [work]
977 CALL CLACP2( 'F', N, N, RWORK( IRU ), N, WORK( IU ),
979 CALL CUNMBR( 'Q', 'L', 'N', N, N, N, A, LDA,
980 $ WORK( ITAUQ ), WORK( IU ), LDWRKU,
981 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
983 * Copy real matrix RWORK(IRVT) to complex matrix VT
984 * Overwrite VT by right singular vectors of R
985 * CWorkspace: need N*N [U] + 2*N [tauq, taup] + N [work]
986 * CWorkspace: prefer N*N [U] + 2*N [tauq, taup] + N*NB [work]
989 CALL CLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
990 CALL CUNMBR( 'P', 'R', 'C', N, N, N, A, LDA,
991 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
992 $ LWORK-NWORK+1, IERR )
994 * Multiply Q in U by left singular vectors of R in
995 * WORK(IU), storing result in A
996 * CWorkspace: need N*N [U]
999 CALL CGEMM( 'N', 'N', M, N, N, CONE, U, LDU, WORK( IU ),
1000 $ LDWRKU, CZERO, A, LDA )
1002 * Copy left singular vectors of A from A to U
1004 CALL CLACPY( 'F', M, N, A, LDA, U, LDU )
1008 ELSE IF( M.GE.MNTHR2 ) THEN
1010 * MNTHR2 <= M < MNTHR1
1012 * Path 5 (M >> N, but not as much as MNTHR1)
1013 * Reduce to bidiagonal form without QR decomposition, use
1014 * CUNGBR and matrix multiplication to compute singular vectors
1023 * CWorkspace: need 2*N [tauq, taup] + M [work]
1024 * CWorkspace: prefer 2*N [tauq, taup] + (M+N)*NB [work]
1025 * RWorkspace: need N [e]
1027 CALL CGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
1028 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
1032 * Path 5n (M >> N, JOBZ='N')
1033 * Compute singular values only
1034 * CWorkspace: need 0
1035 * RWorkspace: need N [e] + BDSPAC
1037 CALL SBDSDC( 'U', 'N', N, S, RWORK( IE ), DUM, 1,DUM,1,
1038 $ DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
1039 ELSE IF( WNTQO ) THEN
1045 * Path 5o (M >> N, JOBZ='O')
1046 * Copy A to VT, generate P**H
1047 * CWorkspace: need 2*N [tauq, taup] + N [work]
1048 * CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
1049 * RWorkspace: need 0
1051 CALL CLACPY( 'U', N, N, A, LDA, VT, LDVT )
1052 CALL CUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
1053 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1056 * CWorkspace: need 2*N [tauq, taup] + N [work]
1057 * CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
1058 * RWorkspace: need 0
1060 CALL CUNGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
1061 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1063 IF( LWORK .GE. M*N + 3*N ) THEN
1065 * WORK( IU ) is M by N
1070 * WORK(IU) is LDWRKU by N
1072 LDWRKU = ( LWORK - 3*N ) / N
1074 NWORK = IU + LDWRKU*N
1076 * Perform bidiagonal SVD, computing left singular vectors
1077 * of bidiagonal matrix in RWORK(IRU) and computing right
1078 * singular vectors of bidiagonal matrix in RWORK(IRVT)
1079 * CWorkspace: need 0
1080 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT] + BDSPAC
1082 CALL SBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
1083 $ N, RWORK( IRVT ), N, DUM, IDUM,
1084 $ RWORK( NRWORK ), IWORK, INFO )
1086 * Multiply real matrix RWORK(IRVT) by P**H in VT,
1087 * storing the result in WORK(IU), copying to VT
1088 * CWorkspace: need 2*N [tauq, taup] + N*N [U]
1089 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT] + 2*N*N [rwork]
1091 CALL CLARCM( N, N, RWORK( IRVT ), N, VT, LDVT,
1092 $ WORK( IU ), LDWRKU, RWORK( NRWORK ) )
1093 CALL CLACPY( 'F', N, N, WORK( IU ), LDWRKU, VT, LDVT )
1095 * Multiply Q in A by real matrix RWORK(IRU), storing the
1096 * result in WORK(IU), copying to A
1097 * CWorkspace: need 2*N [tauq, taup] + N*N [U]
1098 * CWorkspace: prefer 2*N [tauq, taup] + M*N [U]
1099 * RWorkspace: need N [e] + N*N [RU] + 2*N*N [rwork]
1100 * RWorkspace: prefer N [e] + N*N [RU] + 2*M*N [rwork] < N + 5*N*N since M < 2*N here
1103 DO 20 I = 1, M, LDWRKU
1104 CHUNK = MIN( M-I+1, LDWRKU )
1105 CALL CLACRM( CHUNK, N, A( I, 1 ), LDA, RWORK( IRU ),
1106 $ N, WORK( IU ), LDWRKU, RWORK( NRWORK ) )
1107 CALL CLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,
1111 ELSE IF( WNTQS ) THEN
1113 * Path 5s (M >> N, JOBZ='S')
1114 * Copy A to VT, generate P**H
1115 * CWorkspace: need 2*N [tauq, taup] + N [work]
1116 * CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
1117 * RWorkspace: need 0
1119 CALL CLACPY( 'U', N, N, A, LDA, VT, LDVT )
1120 CALL CUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
1121 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1123 * Copy A to U, generate Q
1124 * CWorkspace: need 2*N [tauq, taup] + N [work]
1125 * CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
1126 * RWorkspace: need 0
1128 CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
1129 CALL CUNGBR( 'Q', M, N, N, U, LDU, WORK( ITAUQ ),
1130 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1132 * Perform bidiagonal SVD, computing left singular vectors
1133 * of bidiagonal matrix in RWORK(IRU) and computing right
1134 * singular vectors of bidiagonal matrix in RWORK(IRVT)
1135 * CWorkspace: need 0
1136 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT] + BDSPAC
1141 CALL SBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
1142 $ N, RWORK( IRVT ), N, DUM, IDUM,
1143 $ RWORK( NRWORK ), IWORK, INFO )
1145 * Multiply real matrix RWORK(IRVT) by P**H in VT,
1146 * storing the result in A, copying to VT
1147 * CWorkspace: need 0
1148 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT] + 2*N*N [rwork]
1150 CALL CLARCM( N, N, RWORK( IRVT ), N, VT, LDVT, A, LDA,
1152 CALL CLACPY( 'F', N, N, A, LDA, VT, LDVT )
1154 * Multiply Q in U by real matrix RWORK(IRU), storing the
1155 * result in A, copying to U
1156 * CWorkspace: need 0
1157 * RWorkspace: need N [e] + N*N [RU] + 2*M*N [rwork] < N + 5*N*N since M < 2*N here
1160 CALL CLACRM( M, N, U, LDU, RWORK( IRU ), N, A, LDA,
1162 CALL CLACPY( 'F', M, N, A, LDA, U, LDU )
1165 * Path 5a (M >> N, JOBZ='A')
1166 * Copy A to VT, generate P**H
1167 * CWorkspace: need 2*N [tauq, taup] + N [work]
1168 * CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
1169 * RWorkspace: need 0
1171 CALL CLACPY( 'U', N, N, A, LDA, VT, LDVT )
1172 CALL CUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
1173 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1175 * Copy A to U, generate Q
1176 * CWorkspace: need 2*N [tauq, taup] + M [work]
1177 * CWorkspace: prefer 2*N [tauq, taup] + M*NB [work]
1178 * RWorkspace: need 0
1180 CALL CLACPY( 'L', M, N, A, LDA, U, LDU )
1181 CALL CUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
1182 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1184 * Perform bidiagonal SVD, computing left singular vectors
1185 * of bidiagonal matrix in RWORK(IRU) and computing right
1186 * singular vectors of bidiagonal matrix in RWORK(IRVT)
1187 * CWorkspace: need 0
1188 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT] + BDSPAC
1193 CALL SBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
1194 $ N, RWORK( IRVT ), N, DUM, IDUM,
1195 $ RWORK( NRWORK ), IWORK, INFO )
1197 * Multiply real matrix RWORK(IRVT) by P**H in VT,
1198 * storing the result in A, copying to VT
1199 * CWorkspace: need 0
1200 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT] + 2*N*N [rwork]
1202 CALL CLARCM( N, N, RWORK( IRVT ), N, VT, LDVT, A, LDA,
1204 CALL CLACPY( 'F', N, N, A, LDA, VT, LDVT )
1206 * Multiply Q in U by real matrix RWORK(IRU), storing the
1207 * result in A, copying to U
1208 * CWorkspace: need 0
1209 * RWorkspace: need N [e] + N*N [RU] + 2*M*N [rwork] < N + 5*N*N since M < 2*N here
1212 CALL CLACRM( M, N, U, LDU, RWORK( IRU ), N, A, LDA,
1214 CALL CLACPY( 'F', M, N, A, LDA, U, LDU )
1221 * Path 6 (M >= N, but not much larger)
1222 * Reduce to bidiagonal form without QR decomposition
1223 * Use CUNMBR to compute singular vectors
1232 * CWorkspace: need 2*N [tauq, taup] + M [work]
1233 * CWorkspace: prefer 2*N [tauq, taup] + (M+N)*NB [work]
1234 * RWorkspace: need N [e]
1236 CALL CGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
1237 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
1241 * Path 6n (M >= N, JOBZ='N')
1242 * Compute singular values only
1243 * CWorkspace: need 0
1244 * RWorkspace: need N [e] + BDSPAC
1246 CALL SBDSDC( 'U', 'N', N, S, RWORK( IE ), DUM,1,DUM,1,
1247 $ DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
1248 ELSE IF( WNTQO ) THEN
1253 IF( LWORK .GE. M*N + 3*N ) THEN
1255 * WORK( IU ) is M by N
1260 * WORK( IU ) is LDWRKU by N
1262 LDWRKU = ( LWORK - 3*N ) / N
1264 NWORK = IU + LDWRKU*N
1266 * Path 6o (M >= N, JOBZ='O')
1267 * Perform bidiagonal SVD, computing left singular vectors
1268 * of bidiagonal matrix in RWORK(IRU) and computing right
1269 * singular vectors of bidiagonal matrix in RWORK(IRVT)
1270 * CWorkspace: need 0
1271 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT] + BDSPAC
1273 CALL SBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
1274 $ N, RWORK( IRVT ), N, DUM, IDUM,
1275 $ RWORK( NRWORK ), IWORK, INFO )
1277 * Copy real matrix RWORK(IRVT) to complex matrix VT
1278 * Overwrite VT by right singular vectors of A
1279 * CWorkspace: need 2*N [tauq, taup] + N*N [U] + N [work]
1280 * CWorkspace: prefer 2*N [tauq, taup] + N*N [U] + N*NB [work]
1281 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT]
1283 CALL CLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
1284 CALL CUNMBR( 'P', 'R', 'C', N, N, N, A, LDA,
1285 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
1286 $ LWORK-NWORK+1, IERR )
1288 IF( LWORK .GE. M*N + 3*N ) THEN
1291 * Copy real matrix RWORK(IRU) to complex matrix WORK(IU)
1292 * Overwrite WORK(IU) by left singular vectors of A, copying
1294 * CWorkspace: need 2*N [tauq, taup] + M*N [U] + N [work]
1295 * CWorkspace: prefer 2*N [tauq, taup] + M*N [U] + N*NB [work]
1296 * RWorkspace: need N [e] + N*N [RU]
1298 CALL CLASET( 'F', M, N, CZERO, CZERO, WORK( IU ),
1300 CALL CLACP2( 'F', N, N, RWORK( IRU ), N, WORK( IU ),
1302 CALL CUNMBR( 'Q', 'L', 'N', M, N, N, A, LDA,
1303 $ WORK( ITAUQ ), WORK( IU ), LDWRKU,
1304 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1305 CALL CLACPY( 'F', M, N, WORK( IU ), LDWRKU, A, LDA )
1310 * CWorkspace: need 2*N [tauq, taup] + N*N [U] + N [work]
1311 * CWorkspace: prefer 2*N [tauq, taup] + N*N [U] + N*NB [work]
1312 * RWorkspace: need 0
1314 CALL CUNGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
1315 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1317 * Multiply Q in A by real matrix RWORK(IRU), storing the
1318 * result in WORK(IU), copying to A
1319 * CWorkspace: need 2*N [tauq, taup] + N*N [U]
1320 * CWorkspace: prefer 2*N [tauq, taup] + M*N [U]
1321 * RWorkspace: need N [e] + N*N [RU] + 2*N*N [rwork]
1322 * RWorkspace: prefer N [e] + N*N [RU] + 2*M*N [rwork] < N + 5*N*N since M < 2*N here
1325 DO 30 I = 1, M, LDWRKU
1326 CHUNK = MIN( M-I+1, LDWRKU )
1327 CALL CLACRM( CHUNK, N, A( I, 1 ), LDA,
1328 $ RWORK( IRU ), N, WORK( IU ), LDWRKU,
1330 CALL CLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,
1335 ELSE IF( WNTQS ) THEN
1337 * Path 6s (M >= N, JOBZ='S')
1338 * Perform bidiagonal SVD, computing left singular vectors
1339 * of bidiagonal matrix in RWORK(IRU) and computing right
1340 * singular vectors of bidiagonal matrix in RWORK(IRVT)
1341 * CWorkspace: need 0
1342 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT] + BDSPAC
1347 CALL SBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
1348 $ N, RWORK( IRVT ), N, DUM, IDUM,
1349 $ RWORK( NRWORK ), IWORK, INFO )
1351 * Copy real matrix RWORK(IRU) to complex matrix U
1352 * Overwrite U by left singular vectors of A
1353 * CWorkspace: need 2*N [tauq, taup] + N [work]
1354 * CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
1355 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT]
1357 CALL CLASET( 'F', M, N, CZERO, CZERO, U, LDU )
1358 CALL CLACP2( 'F', N, N, RWORK( IRU ), N, U, LDU )
1359 CALL CUNMBR( 'Q', 'L', 'N', M, N, N, A, LDA,
1360 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
1361 $ LWORK-NWORK+1, IERR )
1363 * Copy real matrix RWORK(IRVT) to complex matrix VT
1364 * Overwrite VT by right singular vectors of A
1365 * CWorkspace: need 2*N [tauq, taup] + N [work]
1366 * CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
1367 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT]
1369 CALL CLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
1370 CALL CUNMBR( 'P', 'R', 'C', N, N, N, A, LDA,
1371 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
1372 $ LWORK-NWORK+1, IERR )
1375 * Path 6a (M >= N, JOBZ='A')
1376 * Perform bidiagonal SVD, computing left singular vectors
1377 * of bidiagonal matrix in RWORK(IRU) and computing right
1378 * singular vectors of bidiagonal matrix in RWORK(IRVT)
1379 * CWorkspace: need 0
1380 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT] + BDSPAC
1385 CALL SBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
1386 $ N, RWORK( IRVT ), N, DUM, IDUM,
1387 $ RWORK( NRWORK ), IWORK, INFO )
1389 * Set the right corner of U to identity matrix
1391 CALL CLASET( 'F', M, M, CZERO, CZERO, U, LDU )
1393 CALL CLASET( 'F', M-N, M-N, CZERO, CONE,
1394 $ U( N+1, N+1 ), LDU )
1397 * Copy real matrix RWORK(IRU) to complex matrix U
1398 * Overwrite U by left singular vectors of A
1399 * CWorkspace: need 2*N [tauq, taup] + M [work]
1400 * CWorkspace: prefer 2*N [tauq, taup] + M*NB [work]
1401 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT]
1403 CALL CLACP2( 'F', N, N, RWORK( IRU ), N, U, LDU )
1404 CALL CUNMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
1405 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
1406 $ LWORK-NWORK+1, IERR )
1408 * Copy real matrix RWORK(IRVT) to complex matrix VT
1409 * Overwrite VT by right singular vectors of A
1410 * CWorkspace: need 2*N [tauq, taup] + N [work]
1411 * CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
1412 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT]
1414 CALL CLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
1415 CALL CUNMBR( 'P', 'R', 'C', N, N, N, A, LDA,
1416 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
1417 $ LWORK-NWORK+1, IERR )
1424 * A has more columns than rows. If A has sufficiently more
1425 * columns than rows, first reduce using the LQ decomposition (if
1426 * sufficient workspace available)
1428 IF( N.GE.MNTHR1 ) THEN
1432 * Path 1t (N >> M, JOBZ='N')
1433 * No singular vectors to be computed
1439 * CWorkspace: need M [tau] + M [work]
1440 * CWorkspace: prefer M [tau] + M*NB [work]
1441 * RWorkspace: need 0
1443 CALL CGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
1444 $ LWORK-NWORK+1, IERR )
1448 CALL CLASET( 'U', M-1, M-1, CZERO, CZERO, A( 1, 2 ),
1455 * Bidiagonalize L in A
1456 * CWorkspace: need 2*M [tauq, taup] + M [work]
1457 * CWorkspace: prefer 2*M [tauq, taup] + 2*M*NB [work]
1458 * RWorkspace: need M [e]
1460 CALL CGEBRD( M, M, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
1461 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
1465 * Perform bidiagonal SVD, compute singular values only
1466 * CWorkspace: need 0
1467 * RWorkspace: need M [e] + BDSPAC
1469 CALL SBDSDC( 'U', 'N', M, S, RWORK( IE ), DUM,1,DUM,1,
1470 $ DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
1472 ELSE IF( WNTQO ) THEN
1474 * Path 2t (N >> M, JOBZ='O')
1475 * M right singular vectors to be overwritten on A and
1476 * M left singular vectors to be computed in U
1481 * WORK(IVT) is M by M
1484 IF( LWORK .GE. M*N + M*M + 3*M ) THEN
1492 * WORK(IL) is M by CHUNK
1495 CHUNK = ( LWORK - M*M - 3*M ) / M
1497 ITAU = IL + LDWRKL*CHUNK
1501 * CWorkspace: need M*M [VT] + M*M [L] + M [tau] + M [work]
1502 * CWorkspace: prefer M*M [VT] + M*M [L] + M [tau] + M*NB [work]
1503 * RWorkspace: need 0
1505 CALL CGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
1506 $ LWORK-NWORK+1, IERR )
1508 * Copy L to WORK(IL), zeroing about above it
1510 CALL CLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWRKL )
1511 CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
1512 $ WORK( IL+LDWRKL ), LDWRKL )
1515 * CWorkspace: need M*M [VT] + M*M [L] + M [tau] + M [work]
1516 * CWorkspace: prefer M*M [VT] + M*M [L] + M [tau] + M*NB [work]
1517 * RWorkspace: need 0
1519 CALL CUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
1520 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1526 * Bidiagonalize L in WORK(IL)
1527 * CWorkspace: need M*M [VT] + M*M [L] + 2*M [tauq, taup] + M [work]
1528 * CWorkspace: prefer M*M [VT] + M*M [L] + 2*M [tauq, taup] + 2*M*NB [work]
1529 * RWorkspace: need M [e]
1531 CALL CGEBRD( M, M, WORK( IL ), LDWRKL, S, RWORK( IE ),
1532 $ WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
1533 $ LWORK-NWORK+1, IERR )
1535 * Perform bidiagonal SVD, computing left singular vectors
1536 * of bidiagonal matrix in RWORK(IRU) and computing right
1537 * singular vectors of bidiagonal matrix in RWORK(IRVT)
1538 * CWorkspace: need 0
1539 * RWorkspace: need M [e] + M*M [RU] + M*M [RVT] + BDSPAC
1544 CALL SBDSDC( 'U', 'I', M, S, RWORK( IE ), RWORK( IRU ),
1545 $ M, RWORK( IRVT ), M, DUM, IDUM,
1546 $ RWORK( NRWORK ), IWORK, INFO )
1548 * Copy real matrix RWORK(IRU) to complex matrix WORK(IU)
1549 * Overwrite WORK(IU) by the left singular vectors of L
1550 * CWorkspace: need M*M [VT] + M*M [L] + 2*M [tauq, taup] + M [work]
1551 * CWorkspace: prefer M*M [VT] + M*M [L] + 2*M [tauq, taup] + M*NB [work]
1552 * RWorkspace: need 0
1554 CALL CLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
1555 CALL CUNMBR( 'Q', 'L', 'N', M, M, M, WORK( IL ), LDWRKL,
1556 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
1557 $ LWORK-NWORK+1, IERR )
1559 * Copy real matrix RWORK(IRVT) to complex matrix WORK(IVT)
1560 * Overwrite WORK(IVT) by the right singular vectors of L
1561 * CWorkspace: need M*M [VT] + M*M [L] + 2*M [tauq, taup] + M [work]
1562 * CWorkspace: prefer M*M [VT] + M*M [L] + 2*M [tauq, taup] + M*NB [work]
1563 * RWorkspace: need 0
1565 CALL CLACP2( 'F', M, M, RWORK( IRVT ), M, WORK( IVT ),
1567 CALL CUNMBR( 'P', 'R', 'C', M, M, M, WORK( IL ), LDWRKL,
1568 $ WORK( ITAUP ), WORK( IVT ), LDWKVT,
1569 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1571 * Multiply right singular vectors of L in WORK(IL) by Q
1572 * in A, storing result in WORK(IL) and copying to A
1573 * CWorkspace: need M*M [VT] + M*M [L]
1574 * CWorkspace: prefer M*M [VT] + M*N [L]
1575 * RWorkspace: need 0
1577 DO 40 I = 1, N, CHUNK
1578 BLK = MIN( N-I+1, CHUNK )
1579 CALL CGEMM( 'N', 'N', M, BLK, M, CONE, WORK( IVT ), M,
1580 $ A( 1, I ), LDA, CZERO, WORK( IL ),
1582 CALL CLACPY( 'F', M, BLK, WORK( IL ), LDWRKL,
1586 ELSE IF( WNTQS ) THEN
1588 * Path 3t (N >> M, JOBZ='S')
1589 * M right singular vectors to be computed in VT and
1590 * M left singular vectors to be computed in U
1594 * WORK(IL) is M by M
1597 ITAU = IL + LDWRKL*M
1601 * CWorkspace: need M*M [L] + M [tau] + M [work]
1602 * CWorkspace: prefer M*M [L] + M [tau] + M*NB [work]
1603 * RWorkspace: need 0
1605 CALL CGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
1606 $ LWORK-NWORK+1, IERR )
1608 * Copy L to WORK(IL), zeroing out above it
1610 CALL CLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWRKL )
1611 CALL CLASET( 'U', M-1, M-1, CZERO, CZERO,
1612 $ WORK( IL+LDWRKL ), LDWRKL )
1615 * CWorkspace: need M*M [L] + M [tau] + M [work]
1616 * CWorkspace: prefer M*M [L] + M [tau] + M*NB [work]
1617 * RWorkspace: need 0
1619 CALL CUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
1620 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1626 * Bidiagonalize L in WORK(IL)
1627 * CWorkspace: need M*M [L] + 2*M [tauq, taup] + M [work]
1628 * CWorkspace: prefer M*M [L] + 2*M [tauq, taup] + 2*M*NB [work]
1629 * RWorkspace: need M [e]
1631 CALL CGEBRD( M, M, WORK( IL ), LDWRKL, S, RWORK( IE ),
1632 $ WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
1633 $ LWORK-NWORK+1, IERR )
1635 * Perform bidiagonal SVD, computing left singular vectors
1636 * of bidiagonal matrix in RWORK(IRU) and computing right
1637 * singular vectors of bidiagonal matrix in RWORK(IRVT)
1638 * CWorkspace: need 0
1639 * RWorkspace: need M [e] + M*M [RU] + M*M [RVT] + BDSPAC
1644 CALL SBDSDC( 'U', 'I', M, S, RWORK( IE ), RWORK( IRU ),
1645 $ M, RWORK( IRVT ), M, DUM, IDUM,
1646 $ RWORK( NRWORK ), IWORK, INFO )
1648 * Copy real matrix RWORK(IRU) to complex matrix U
1649 * Overwrite U by left singular vectors of L
1650 * CWorkspace: need M*M [L] + 2*M [tauq, taup] + M [work]
1651 * CWorkspace: prefer M*M [L] + 2*M [tauq, taup] + M*NB [work]
1652 * RWorkspace: need 0
1654 CALL CLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
1655 CALL CUNMBR( 'Q', 'L', 'N', M, M, M, WORK( IL ), LDWRKL,
1656 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
1657 $ LWORK-NWORK+1, IERR )
1659 * Copy real matrix RWORK(IRVT) to complex matrix VT
1660 * Overwrite VT by left singular vectors of L
1661 * CWorkspace: need M*M [L] + 2*M [tauq, taup] + M [work]
1662 * CWorkspace: prefer M*M [L] + 2*M [tauq, taup] + M*NB [work]
1663 * RWorkspace: need 0
1665 CALL CLACP2( 'F', M, M, RWORK( IRVT ), M, VT, LDVT )
1666 CALL CUNMBR( 'P', 'R', 'C', M, M, M, WORK( IL ), LDWRKL,
1667 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
1668 $ LWORK-NWORK+1, IERR )
1670 * Copy VT to WORK(IL), multiply right singular vectors of L
1671 * in WORK(IL) by Q in A, storing result in VT
1672 * CWorkspace: need M*M [L]
1673 * RWorkspace: need 0
1675 CALL CLACPY( 'F', M, M, VT, LDVT, WORK( IL ), LDWRKL )
1676 CALL CGEMM( 'N', 'N', M, N, M, CONE, WORK( IL ), LDWRKL,
1677 $ A, LDA, CZERO, VT, LDVT )
1679 ELSE IF( WNTQA ) THEN
1681 * Path 4t (N >> M, JOBZ='A')
1682 * N right singular vectors to be computed in VT and
1683 * M left singular vectors to be computed in U
1687 * WORK(IVT) is M by M
1690 ITAU = IVT + LDWKVT*M
1693 * Compute A=L*Q, copying result to VT
1694 * CWorkspace: need M*M [VT] + M [tau] + M [work]
1695 * CWorkspace: prefer M*M [VT] + M [tau] + M*NB [work]
1696 * RWorkspace: need 0
1698 CALL CGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
1699 $ LWORK-NWORK+1, IERR )
1700 CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
1703 * CWorkspace: need M*M [VT] + M [tau] + N [work]
1704 * CWorkspace: prefer M*M [VT] + M [tau] + N*NB [work]
1705 * RWorkspace: need 0
1707 CALL CUNGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
1708 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1710 * Produce L in A, zeroing out above it
1712 CALL CLASET( 'U', M-1, M-1, CZERO, CZERO, A( 1, 2 ),
1719 * Bidiagonalize L in A
1720 * CWorkspace: need M*M [VT] + 2*M [tauq, taup] + M [work]
1721 * CWorkspace: prefer M*M [VT] + 2*M [tauq, taup] + 2*M*NB [work]
1722 * RWorkspace: need M [e]
1724 CALL CGEBRD( M, M, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
1725 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
1728 * Perform bidiagonal SVD, computing left singular vectors
1729 * of bidiagonal matrix in RWORK(IRU) and computing right
1730 * singular vectors of bidiagonal matrix in RWORK(IRVT)
1731 * CWorkspace: need 0
1732 * RWorkspace: need M [e] + M*M [RU] + M*M [RVT] + BDSPAC
1737 CALL SBDSDC( 'U', 'I', M, S, RWORK( IE ), RWORK( IRU ),
1738 $ M, RWORK( IRVT ), M, DUM, IDUM,
1739 $ RWORK( NRWORK ), IWORK, INFO )
1741 * Copy real matrix RWORK(IRU) to complex matrix U
1742 * Overwrite U by left singular vectors of L
1743 * CWorkspace: need M*M [VT] + 2*M [tauq, taup] + M [work]
1744 * CWorkspace: prefer M*M [VT] + 2*M [tauq, taup] + M*NB [work]
1745 * RWorkspace: need 0
1747 CALL CLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
1748 CALL CUNMBR( 'Q', 'L', 'N', M, M, M, A, LDA,
1749 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
1750 $ LWORK-NWORK+1, IERR )
1752 * Copy real matrix RWORK(IRVT) to complex matrix WORK(IVT)
1753 * Overwrite WORK(IVT) by right singular vectors of L
1754 * CWorkspace: need M*M [VT] + 2*M [tauq, taup] + M [work]
1755 * CWorkspace: prefer M*M [VT] + 2*M [tauq, taup] + M*NB [work]
1756 * RWorkspace: need 0
1758 CALL CLACP2( 'F', M, M, RWORK( IRVT ), M, WORK( IVT ),
1760 CALL CUNMBR( 'P', 'R', 'C', M, M, M, A, LDA,
1761 $ WORK( ITAUP ), WORK( IVT ), LDWKVT,
1762 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1764 * Multiply right singular vectors of L in WORK(IVT) by
1765 * Q in VT, storing result in A
1766 * CWorkspace: need M*M [VT]
1767 * RWorkspace: need 0
1769 CALL CGEMM( 'N', 'N', M, N, M, CONE, WORK( IVT ), LDWKVT,
1770 $ VT, LDVT, CZERO, A, LDA )
1772 * Copy right singular vectors of A from A to VT
1774 CALL CLACPY( 'F', M, N, A, LDA, VT, LDVT )
1778 ELSE IF( N.GE.MNTHR2 ) THEN
1780 * MNTHR2 <= N < MNTHR1
1782 * Path 5t (N >> M, but not as much as MNTHR1)
1783 * Reduce to bidiagonal form without QR decomposition, use
1784 * CUNGBR and matrix multiplication to compute singular vectors
1793 * CWorkspace: need 2*M [tauq, taup] + N [work]
1794 * CWorkspace: prefer 2*M [tauq, taup] + (M+N)*NB [work]
1795 * RWorkspace: need M [e]
1797 CALL CGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
1798 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
1803 * Path 5tn (N >> M, JOBZ='N')
1804 * Compute singular values only
1805 * CWorkspace: need 0
1806 * RWorkspace: need M [e] + BDSPAC
1808 CALL SBDSDC( 'L', 'N', M, S, RWORK( IE ), DUM,1,DUM,1,
1809 $ DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
1810 ELSE IF( WNTQO ) THEN
1816 * Path 5to (N >> M, JOBZ='O')
1817 * Copy A to U, generate Q
1818 * CWorkspace: need 2*M [tauq, taup] + M [work]
1819 * CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
1820 * RWorkspace: need 0
1822 CALL CLACPY( 'L', M, M, A, LDA, U, LDU )
1823 CALL CUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
1824 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1826 * Generate P**H in A
1827 * CWorkspace: need 2*M [tauq, taup] + M [work]
1828 * CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
1829 * RWorkspace: need 0
1831 CALL CUNGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
1832 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1835 IF( LWORK .GE. M*N + 3*M ) THEN
1837 * WORK( IVT ) is M by N
1839 NWORK = IVT + LDWKVT*N
1843 * WORK( IVT ) is M by CHUNK
1845 CHUNK = ( LWORK - 3*M ) / M
1846 NWORK = IVT + LDWKVT*CHUNK
1849 * Perform bidiagonal SVD, computing left singular vectors
1850 * of bidiagonal matrix in RWORK(IRU) and computing right
1851 * singular vectors of bidiagonal matrix in RWORK(IRVT)
1852 * CWorkspace: need 0
1853 * RWorkspace: need M [e] + M*M [RVT] + M*M [RU] + BDSPAC
1855 CALL SBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
1856 $ M, RWORK( IRVT ), M, DUM, IDUM,
1857 $ RWORK( NRWORK ), IWORK, INFO )
1859 * Multiply Q in U by real matrix RWORK(IRVT)
1860 * storing the result in WORK(IVT), copying to U
1861 * CWorkspace: need 2*M [tauq, taup] + M*M [VT]
1862 * RWorkspace: need M [e] + M*M [RVT] + M*M [RU] + 2*M*M [rwork]
1864 CALL CLACRM( M, M, U, LDU, RWORK( IRU ), M, WORK( IVT ),
1865 $ LDWKVT, RWORK( NRWORK ) )
1866 CALL CLACPY( 'F', M, M, WORK( IVT ), LDWKVT, U, LDU )
1868 * Multiply RWORK(IRVT) by P**H in A, storing the
1869 * result in WORK(IVT), copying to A
1870 * CWorkspace: need 2*M [tauq, taup] + M*M [VT]
1871 * CWorkspace: prefer 2*M [tauq, taup] + M*N [VT]
1872 * RWorkspace: need M [e] + M*M [RVT] + 2*M*M [rwork]
1873 * RWorkspace: prefer M [e] + M*M [RVT] + 2*M*N [rwork] < M + 5*M*M since N < 2*M here
1876 DO 50 I = 1, N, CHUNK
1877 BLK = MIN( N-I+1, CHUNK )
1878 CALL CLARCM( M, BLK, RWORK( IRVT ), M, A( 1, I ), LDA,
1879 $ WORK( IVT ), LDWKVT, RWORK( NRWORK ) )
1880 CALL CLACPY( 'F', M, BLK, WORK( IVT ), LDWKVT,
1883 ELSE IF( WNTQS ) THEN
1885 * Path 5ts (N >> M, JOBZ='S')
1886 * Copy A to U, generate Q
1887 * CWorkspace: need 2*M [tauq, taup] + M [work]
1888 * CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
1889 * RWorkspace: need 0
1891 CALL CLACPY( 'L', M, M, A, LDA, U, LDU )
1892 CALL CUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
1893 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1895 * Copy A to VT, generate P**H
1896 * CWorkspace: need 2*M [tauq, taup] + M [work]
1897 * CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
1898 * RWorkspace: need 0
1900 CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
1901 CALL CUNGBR( 'P', M, N, M, VT, LDVT, WORK( ITAUP ),
1902 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1904 * Perform bidiagonal SVD, computing left singular vectors
1905 * of bidiagonal matrix in RWORK(IRU) and computing right
1906 * singular vectors of bidiagonal matrix in RWORK(IRVT)
1907 * CWorkspace: need 0
1908 * RWorkspace: need M [e] + M*M [RVT] + M*M [RU] + BDSPAC
1913 CALL SBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
1914 $ M, RWORK( IRVT ), M, DUM, IDUM,
1915 $ RWORK( NRWORK ), IWORK, INFO )
1917 * Multiply Q in U by real matrix RWORK(IRU), storing the
1918 * result in A, copying to U
1919 * CWorkspace: need 0
1920 * RWorkspace: need M [e] + M*M [RVT] + M*M [RU] + 2*M*M [rwork]
1922 CALL CLACRM( M, M, U, LDU, RWORK( IRU ), M, A, LDA,
1924 CALL CLACPY( 'F', M, M, A, LDA, U, LDU )
1926 * Multiply real matrix RWORK(IRVT) by P**H in VT,
1927 * storing the result in A, copying to VT
1928 * CWorkspace: need 0
1929 * RWorkspace: need M [e] + M*M [RVT] + 2*M*N [rwork] < M + 5*M*M since N < 2*M here
1932 CALL CLARCM( M, N, RWORK( IRVT ), M, VT, LDVT, A, LDA,
1934 CALL CLACPY( 'F', M, N, A, LDA, VT, LDVT )
1937 * Path 5ta (N >> M, JOBZ='A')
1938 * Copy A to U, generate Q
1939 * CWorkspace: need 2*M [tauq, taup] + M [work]
1940 * CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
1941 * RWorkspace: need 0
1943 CALL CLACPY( 'L', M, M, A, LDA, U, LDU )
1944 CALL CUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
1945 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1947 * Copy A to VT, generate P**H
1948 * CWorkspace: need 2*M [tauq, taup] + N [work]
1949 * CWorkspace: prefer 2*M [tauq, taup] + N*NB [work]
1950 * RWorkspace: need 0
1952 CALL CLACPY( 'U', M, N, A, LDA, VT, LDVT )
1953 CALL CUNGBR( 'P', N, N, M, VT, LDVT, WORK( ITAUP ),
1954 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1956 * Perform bidiagonal SVD, computing left singular vectors
1957 * of bidiagonal matrix in RWORK(IRU) and computing right
1958 * singular vectors of bidiagonal matrix in RWORK(IRVT)
1959 * CWorkspace: need 0
1960 * RWorkspace: need M [e] + M*M [RVT] + M*M [RU] + BDSPAC
1965 CALL SBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
1966 $ M, RWORK( IRVT ), M, DUM, IDUM,
1967 $ RWORK( NRWORK ), IWORK, INFO )
1969 * Multiply Q in U by real matrix RWORK(IRU), storing the
1970 * result in A, copying to U
1971 * CWorkspace: need 0
1972 * RWorkspace: need M [e] + M*M [RVT] + M*M [RU] + 2*M*M [rwork]
1974 CALL CLACRM( M, M, U, LDU, RWORK( IRU ), M, A, LDA,
1976 CALL CLACPY( 'F', M, M, A, LDA, U, LDU )
1978 * Multiply real matrix RWORK(IRVT) by P**H in VT,
1979 * storing the result in A, copying to VT
1980 * CWorkspace: need 0
1981 * RWorkspace: need M [e] + M*M [RVT] + 2*M*N [rwork] < M + 5*M*M since N < 2*M here
1984 CALL CLARCM( M, N, RWORK( IRVT ), M, VT, LDVT, A, LDA,
1986 CALL CLACPY( 'F', M, N, A, LDA, VT, LDVT )
1993 * Path 6t (N > M, but not much larger)
1994 * Reduce to bidiagonal form without LQ decomposition
1995 * Use CUNMBR to compute singular vectors
2004 * CWorkspace: need 2*M [tauq, taup] + N [work]
2005 * CWorkspace: prefer 2*M [tauq, taup] + (M+N)*NB [work]
2006 * RWorkspace: need M [e]
2008 CALL CGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
2009 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
2013 * Path 6tn (N > M, JOBZ='N')
2014 * Compute singular values only
2015 * CWorkspace: need 0
2016 * RWorkspace: need M [e] + BDSPAC
2018 CALL SBDSDC( 'L', 'N', M, S, RWORK( IE ), DUM,1,DUM,1,
2019 $ DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
2020 ELSE IF( WNTQO ) THEN
2021 * Path 6to (N > M, JOBZ='O')
2024 IF( LWORK .GE. M*N + 3*M ) THEN
2026 * WORK( IVT ) is M by N
2028 CALL CLASET( 'F', M, N, CZERO, CZERO, WORK( IVT ),
2030 NWORK = IVT + LDWKVT*N
2033 * WORK( IVT ) is M by CHUNK
2035 CHUNK = ( LWORK - 3*M ) / M
2036 NWORK = IVT + LDWKVT*CHUNK
2039 * Perform bidiagonal SVD, computing left singular vectors
2040 * of bidiagonal matrix in RWORK(IRU) and computing right
2041 * singular vectors of bidiagonal matrix in RWORK(IRVT)
2042 * CWorkspace: need 0
2043 * RWorkspace: need M [e] + M*M [RVT] + M*M [RU] + BDSPAC
2048 CALL SBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
2049 $ M, RWORK( IRVT ), M, DUM, IDUM,
2050 $ RWORK( NRWORK ), IWORK, INFO )
2052 * Copy real matrix RWORK(IRU) to complex matrix U
2053 * Overwrite U by left singular vectors of A
2054 * CWorkspace: need 2*M [tauq, taup] + M*M [VT] + M [work]
2055 * CWorkspace: prefer 2*M [tauq, taup] + M*M [VT] + M*NB [work]
2056 * RWorkspace: need M [e] + M*M [RVT] + M*M [RU]
2058 CALL CLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
2059 CALL CUNMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
2060 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
2061 $ LWORK-NWORK+1, IERR )
2063 IF( LWORK .GE. M*N + 3*M ) THEN
2066 * Copy real matrix RWORK(IRVT) to complex matrix WORK(IVT)
2067 * Overwrite WORK(IVT) by right singular vectors of A,
2069 * CWorkspace: need 2*M [tauq, taup] + M*N [VT] + M [work]
2070 * CWorkspace: prefer 2*M [tauq, taup] + M*N [VT] + M*NB [work]
2071 * RWorkspace: need M [e] + M*M [RVT]
2073 CALL CLACP2( 'F', M, M, RWORK( IRVT ), M, WORK( IVT ),
2075 CALL CUNMBR( 'P', 'R', 'C', M, N, M, A, LDA,
2076 $ WORK( ITAUP ), WORK( IVT ), LDWKVT,
2077 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
2078 CALL CLACPY( 'F', M, N, WORK( IVT ), LDWKVT, A, LDA )
2082 * Generate P**H in A
2083 * CWorkspace: need 2*M [tauq, taup] + M*M [VT] + M [work]
2084 * CWorkspace: prefer 2*M [tauq, taup] + M*M [VT] + M*NB [work]
2085 * RWorkspace: need 0
2087 CALL CUNGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
2088 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
2090 * Multiply Q in A by real matrix RWORK(IRU), storing the
2091 * result in WORK(IU), copying to A
2092 * CWorkspace: need 2*M [tauq, taup] + M*M [VT]
2093 * CWorkspace: prefer 2*M [tauq, taup] + M*N [VT]
2094 * RWorkspace: need M [e] + M*M [RVT] + 2*M*M [rwork]
2095 * RWorkspace: prefer M [e] + M*M [RVT] + 2*M*N [rwork] < M + 5*M*M since N < 2*M here
2098 DO 60 I = 1, N, CHUNK
2099 BLK = MIN( N-I+1, CHUNK )
2100 CALL CLARCM( M, BLK, RWORK( IRVT ), M, A( 1, I ),
2101 $ LDA, WORK( IVT ), LDWKVT,
2103 CALL CLACPY( 'F', M, BLK, WORK( IVT ), LDWKVT,
2107 ELSE IF( WNTQS ) THEN
2109 * Path 6ts (N > M, JOBZ='S')
2110 * Perform bidiagonal SVD, computing left singular vectors
2111 * of bidiagonal matrix in RWORK(IRU) and computing right
2112 * singular vectors of bidiagonal matrix in RWORK(IRVT)
2113 * CWorkspace: need 0
2114 * RWorkspace: need M [e] + M*M [RVT] + M*M [RU] + BDSPAC
2119 CALL SBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
2120 $ M, RWORK( IRVT ), M, DUM, IDUM,
2121 $ RWORK( NRWORK ), IWORK, INFO )
2123 * Copy real matrix RWORK(IRU) to complex matrix U
2124 * Overwrite U by left singular vectors of A
2125 * CWorkspace: need 2*M [tauq, taup] + M [work]
2126 * CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
2127 * RWorkspace: need M [e] + M*M [RVT] + M*M [RU]
2129 CALL CLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
2130 CALL CUNMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
2131 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
2132 $ LWORK-NWORK+1, IERR )
2134 * Copy real matrix RWORK(IRVT) to complex matrix VT
2135 * Overwrite VT by right singular vectors of A
2136 * CWorkspace: need 2*M [tauq, taup] + M [work]
2137 * CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
2138 * RWorkspace: need M [e] + M*M [RVT]
2140 CALL CLASET( 'F', M, N, CZERO, CZERO, VT, LDVT )
2141 CALL CLACP2( 'F', M, M, RWORK( IRVT ), M, VT, LDVT )
2142 CALL CUNMBR( 'P', 'R', 'C', M, N, M, A, LDA,
2143 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
2144 $ LWORK-NWORK+1, IERR )
2147 * Path 6ta (N > M, JOBZ='A')
2148 * Perform bidiagonal SVD, computing left singular vectors
2149 * of bidiagonal matrix in RWORK(IRU) and computing right
2150 * singular vectors of bidiagonal matrix in RWORK(IRVT)
2151 * CWorkspace: need 0
2152 * RWorkspace: need M [e] + M*M [RVT] + M*M [RU] + BDSPAC
2158 CALL SBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
2159 $ M, RWORK( IRVT ), M, DUM, IDUM,
2160 $ RWORK( NRWORK ), IWORK, INFO )
2162 * Copy real matrix RWORK(IRU) to complex matrix U
2163 * Overwrite U by left singular vectors of A
2164 * CWorkspace: need 2*M [tauq, taup] + M [work]
2165 * CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
2166 * RWorkspace: need M [e] + M*M [RVT] + M*M [RU]
2168 CALL CLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
2169 CALL CUNMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
2170 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
2171 $ LWORK-NWORK+1, IERR )
2173 * Set all of VT to identity matrix
2175 CALL CLASET( 'F', N, N, CZERO, CONE, VT, LDVT )
2177 * Copy real matrix RWORK(IRVT) to complex matrix VT
2178 * Overwrite VT by right singular vectors of A
2179 * CWorkspace: need 2*M [tauq, taup] + N [work]
2180 * CWorkspace: prefer 2*M [tauq, taup] + N*NB [work]
2181 * RWorkspace: need M [e] + M*M [RVT]
2183 CALL CLACP2( 'F', M, M, RWORK( IRVT ), M, VT, LDVT )
2184 CALL CUNMBR( 'P', 'R', 'C', N, N, M, A, LDA,
2185 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
2186 $ LWORK-NWORK+1, IERR )
2193 * Undo scaling if necessary
2195 IF( ISCL.EQ.1 ) THEN
2196 IF( ANRM.GT.BIGNUM )
2197 $ CALL SLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,
2199 IF( INFO.NE.0 .AND. ANRM.GT.BIGNUM )
2200 $ CALL SLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN-1, 1,
2201 $ RWORK( IE ), MINMN, IERR )
2202 IF( ANRM.LT.SMLNUM )
2203 $ CALL SLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,
2205 IF( INFO.NE.0 .AND. ANRM.LT.SMLNUM )
2206 $ CALL SLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN-1, 1,
2207 $ RWORK( IE ), MINMN, IERR )
2210 * Return optimal workspace in WORK(1)