3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download ZGESDD + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zgesdd.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zgesdd.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zgesdd.f">
21 * SUBROUTINE ZGESDD( 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 * DOUBLE PRECISION RWORK( * ), S( * )
31 * COMPLEX*16 A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
41 *> ZGESDD 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*16 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 DOUBLE PRECISION array, dimension (min(M,N))
120 *> The singular values of A, sorted so that S(i) >= S(i+1).
125 *> U is COMPLEX*16 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*16 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*16 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 DOUBLE PRECISION 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 DBDSDC did not converge.
210 *> \author Univ. of Tennessee
211 *> \author Univ. of California Berkeley
212 *> \author Univ. of Colorado Denver
217 *> \ingroup complex16GEsing
219 *> \par Contributors:
222 *> Ming Gu and Huan Ren, Computer Science Division, University of
223 *> California at Berkeley, USA
225 *> @precisions fortran z -> c
226 * =====================================================================
227 SUBROUTINE ZGESDD( JOBZ, M, N, A, LDA, S, U, LDU, VT, LDVT,
228 $ WORK, LWORK, RWORK, IWORK, INFO )
231 * -- LAPACK driver routine (version 3.6.1) --
232 * -- LAPACK is a software package provided by Univ. of Tennessee, --
233 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
236 * .. Scalar Arguments ..
238 INTEGER INFO, LDA, LDU, LDVT, LWORK, M, N
240 * .. Array Arguments ..
242 DOUBLE PRECISION RWORK( * ), S( * )
243 COMPLEX*16 A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
247 * =====================================================================
250 COMPLEX*16 CZERO, CONE
251 PARAMETER ( CZERO = ( 0.0D+0, 0.0D+0 ),
252 $ CONE = ( 1.0D+0, 0.0D+0 ) )
253 DOUBLE PRECISION ZERO, ONE
254 PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
256 * .. Local Scalars ..
257 LOGICAL LQUERY, WNTQA, WNTQAS, WNTQN, WNTQO, WNTQS
258 INTEGER BLK, CHUNK, I, IE, IERR, IL, IR, IRU, IRVT,
259 $ ISCL, ITAU, ITAUP, ITAUQ, IU, IVT, LDWKVT,
260 $ LDWRKL, LDWRKR, LDWRKU, MAXWRK, MINMN, MINWRK,
261 $ MNTHR1, MNTHR2, NRWORK, NWORK, WRKBL
262 INTEGER LWORK_ZGEBRD_MN, LWORK_ZGEBRD_MM,
263 $ LWORK_ZGEBRD_NN, LWORK_ZGELQF_MN,
265 $ LWORK_ZUNGBR_P_MN, LWORK_ZUNGBR_P_NN,
266 $ LWORK_ZUNGBR_Q_MN, LWORK_ZUNGBR_Q_MM,
267 $ LWORK_ZUNGLQ_MN, LWORK_ZUNGLQ_NN,
268 $ LWORK_ZUNGQR_MM, LWORK_ZUNGQR_MN,
269 $ LWORK_ZUNMBR_PRC_MM, LWORK_ZUNMBR_QLN_MM,
270 $ LWORK_ZUNMBR_PRC_MN, LWORK_ZUNMBR_QLN_MN,
271 $ LWORK_ZUNMBR_PRC_NN, LWORK_ZUNMBR_QLN_NN
272 DOUBLE PRECISION ANRM, BIGNUM, EPS, SMLNUM
276 DOUBLE PRECISION DUM( 1 )
279 * .. External Subroutines ..
280 EXTERNAL DBDSDC, DLASCL, XERBLA, ZGEBRD, ZGELQF, ZGEMM,
281 $ ZGEQRF, ZLACP2, ZLACPY, ZLACRM, ZLARCM, ZLASCL,
282 $ ZLASET, ZUNGBR, ZUNGLQ, ZUNGQR, ZUNMBR
284 * .. External Functions ..
286 DOUBLE PRECISION DLAMCH, ZLANGE
287 EXTERNAL LSAME, DLAMCH, ZLANGE
289 * .. Intrinsic Functions ..
290 INTRINSIC INT, MAX, MIN, SQRT
292 * .. Executable Statements ..
294 * Test the input arguments
298 MNTHR1 = INT( MINMN*17.0D0 / 9.0D0 )
299 MNTHR2 = INT( MINMN*5.0D0 / 3.0D0 )
300 WNTQA = LSAME( JOBZ, 'A' )
301 WNTQS = LSAME( JOBZ, 'S' )
302 WNTQAS = WNTQA .OR. WNTQS
303 WNTQO = LSAME( JOBZ, 'O' )
304 WNTQN = LSAME( JOBZ, 'N' )
305 LQUERY = ( LWORK.EQ.-1 )
309 IF( .NOT.( WNTQA .OR. WNTQS .OR. WNTQO .OR. WNTQN ) ) THEN
311 ELSE IF( M.LT.0 ) THEN
313 ELSE IF( N.LT.0 ) THEN
315 ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
317 ELSE IF( LDU.LT.1 .OR. ( WNTQAS .AND. LDU.LT.M ) .OR.
318 $ ( WNTQO .AND. M.LT.N .AND. LDU.LT.M ) ) THEN
320 ELSE IF( LDVT.LT.1 .OR. ( WNTQA .AND. LDVT.LT.N ) .OR.
321 $ ( WNTQS .AND. LDVT.LT.MINMN ) .OR.
322 $ ( WNTQO .AND. M.GE.N .AND. LDVT.LT.N ) ) THEN
327 * Note: Comments in the code beginning "Workspace:" describe the
328 * minimal amount of workspace allocated at that point in the code,
329 * as well as the preferred amount for good performance.
330 * CWorkspace refers to complex workspace, and RWorkspace to
331 * real workspace. NB refers to the optimal block size for the
332 * immediately following subroutine, as returned by ILAENV.)
334 IF( INFO.EQ.0 .AND. M.GT.0 .AND. N.GT.0 ) THEN
337 * There is no complex work space needed for bidiagonal SVD
338 * The real work space needed for bidiagonal SVD (dbdsdc) is
339 * BDSPAC = 3*N*N + 4*N for singular values and vectors;
340 * BDSPAC = 4*N for singular values only;
341 * not including e, RU, and RVT matrices.
343 * Compute space preferred for each routine
344 CALL ZGEBRD( M, N, CDUM(1), M, DUM(1), DUM(1), CDUM(1),
345 $ CDUM(1), CDUM(1), -1, IERR )
346 LWORK_ZGEBRD_MN = INT( CDUM(1) )
348 CALL ZGEBRD( N, N, CDUM(1), N, DUM(1), DUM(1), CDUM(1),
349 $ CDUM(1), CDUM(1), -1, IERR )
350 LWORK_ZGEBRD_NN = INT( CDUM(1) )
352 CALL ZGEQRF( M, N, CDUM(1), M, CDUM(1), CDUM(1), -1, IERR )
353 LWORK_ZGEQRF_MN = INT( CDUM(1) )
355 CALL ZUNGBR( 'P', N, N, N, CDUM(1), N, CDUM(1), CDUM(1),
357 LWORK_ZUNGBR_P_NN = INT( CDUM(1) )
359 CALL ZUNGBR( 'Q', M, M, N, CDUM(1), M, CDUM(1), CDUM(1),
361 LWORK_ZUNGBR_Q_MM = INT( CDUM(1) )
363 CALL ZUNGBR( 'Q', M, N, N, CDUM(1), M, CDUM(1), CDUM(1),
365 LWORK_ZUNGBR_Q_MN = INT( CDUM(1) )
367 CALL ZUNGQR( M, M, N, CDUM(1), M, CDUM(1), CDUM(1),
369 LWORK_ZUNGQR_MM = INT( CDUM(1) )
371 CALL ZUNGQR( M, N, N, CDUM(1), M, CDUM(1), CDUM(1),
373 LWORK_ZUNGQR_MN = INT( CDUM(1) )
375 CALL ZUNMBR( 'P', 'R', 'C', N, N, N, CDUM(1), N, CDUM(1),
376 $ CDUM(1), N, CDUM(1), -1, IERR )
377 LWORK_ZUNMBR_PRC_NN = INT( CDUM(1) )
379 CALL ZUNMBR( 'Q', 'L', 'N', M, M, N, CDUM(1), M, CDUM(1),
380 $ CDUM(1), M, CDUM(1), -1, IERR )
381 LWORK_ZUNMBR_QLN_MM = INT( CDUM(1) )
383 CALL ZUNMBR( 'Q', 'L', 'N', M, N, N, CDUM(1), M, CDUM(1),
384 $ CDUM(1), M, CDUM(1), -1, IERR )
385 LWORK_ZUNMBR_QLN_MN = INT( CDUM(1) )
387 CALL ZUNMBR( 'Q', 'L', 'N', N, N, N, CDUM(1), N, CDUM(1),
388 $ CDUM(1), N, CDUM(1), -1, IERR )
389 LWORK_ZUNMBR_QLN_NN = INT( CDUM(1) )
391 IF( M.GE.MNTHR1 ) THEN
394 * Path 1 (M >> N, JOBZ='N')
396 MAXWRK = N + LWORK_ZGEQRF_MN
397 MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZGEBRD_NN )
399 ELSE IF( WNTQO ) THEN
401 * Path 2 (M >> N, JOBZ='O')
403 WRKBL = N + LWORK_ZGEQRF_MN
404 WRKBL = MAX( WRKBL, N + LWORK_ZUNGQR_MN )
405 WRKBL = MAX( WRKBL, 2*N + LWORK_ZGEBRD_NN )
406 WRKBL = MAX( WRKBL, 2*N + LWORK_ZUNMBR_QLN_NN )
407 WRKBL = MAX( WRKBL, 2*N + LWORK_ZUNMBR_PRC_NN )
408 MAXWRK = M*N + N*N + WRKBL
410 ELSE IF( WNTQS ) THEN
412 * Path 3 (M >> N, JOBZ='S')
414 WRKBL = N + LWORK_ZGEQRF_MN
415 WRKBL = MAX( WRKBL, N + LWORK_ZUNGQR_MN )
416 WRKBL = MAX( WRKBL, 2*N + LWORK_ZGEBRD_NN )
417 WRKBL = MAX( WRKBL, 2*N + LWORK_ZUNMBR_QLN_NN )
418 WRKBL = MAX( WRKBL, 2*N + LWORK_ZUNMBR_PRC_NN )
421 ELSE IF( WNTQA ) THEN
423 * Path 4 (M >> N, JOBZ='A')
425 WRKBL = N + LWORK_ZGEQRF_MN
426 WRKBL = MAX( WRKBL, N + LWORK_ZUNGQR_MM )
427 WRKBL = MAX( WRKBL, 2*N + LWORK_ZGEBRD_NN )
428 WRKBL = MAX( WRKBL, 2*N + LWORK_ZUNMBR_QLN_NN )
429 WRKBL = MAX( WRKBL, 2*N + LWORK_ZUNMBR_PRC_NN )
431 MINWRK = N*N + MAX( 3*N, N + M )
433 ELSE IF( M.GE.MNTHR2 ) THEN
435 * Path 5 (M >> N, but not as much as MNTHR1)
437 MAXWRK = 2*N + LWORK_ZGEBRD_MN
440 * Path 5o (M >> N, JOBZ='O')
441 MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNGBR_P_NN )
442 MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNGBR_Q_MN )
443 MAXWRK = MAXWRK + M*N
444 MINWRK = MINWRK + N*N
445 ELSE IF( WNTQS ) THEN
446 * Path 5s (M >> N, JOBZ='S')
447 MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNGBR_P_NN )
448 MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNGBR_Q_MN )
449 ELSE IF( WNTQA ) THEN
450 * Path 5a (M >> N, JOBZ='A')
451 MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNGBR_P_NN )
452 MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNGBR_Q_MM )
456 * Path 6 (M >= N, but not much larger)
458 MAXWRK = 2*N + LWORK_ZGEBRD_MN
461 * Path 6o (M >= N, JOBZ='O')
462 MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNMBR_PRC_NN )
463 MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNMBR_QLN_MN )
464 MAXWRK = MAXWRK + M*N
465 MINWRK = MINWRK + N*N
466 ELSE IF( WNTQS ) THEN
467 * Path 6s (M >= N, JOBZ='S')
468 MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNMBR_QLN_MN )
469 MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNMBR_PRC_NN )
470 ELSE IF( WNTQA ) THEN
471 * Path 6a (M >= N, JOBZ='A')
472 MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNMBR_QLN_MM )
473 MAXWRK = MAX( MAXWRK, 2*N + LWORK_ZUNMBR_PRC_NN )
478 * There is no complex work space needed for bidiagonal SVD
479 * The real work space needed for bidiagonal SVD (dbdsdc) is
480 * BDSPAC = 3*M*M + 4*M for singular values and vectors;
481 * BDSPAC = 4*M for singular values only;
482 * not including e, RU, and RVT matrices.
484 * Compute space preferred for each routine
485 CALL ZGEBRD( M, N, CDUM(1), M, DUM(1), DUM(1), CDUM(1),
486 $ CDUM(1), CDUM(1), -1, IERR )
487 LWORK_ZGEBRD_MN = INT( CDUM(1) )
489 CALL ZGEBRD( M, M, CDUM(1), M, DUM(1), DUM(1), CDUM(1),
490 $ CDUM(1), CDUM(1), -1, IERR )
491 LWORK_ZGEBRD_MM = INT( CDUM(1) )
493 CALL ZGELQF( M, N, CDUM(1), M, CDUM(1), CDUM(1), -1, IERR )
494 LWORK_ZGELQF_MN = INT( CDUM(1) )
496 CALL ZUNGBR( 'P', M, N, M, CDUM(1), M, CDUM(1), CDUM(1),
498 LWORK_ZUNGBR_P_MN = INT( CDUM(1) )
500 CALL ZUNGBR( 'P', N, N, M, CDUM(1), N, CDUM(1), CDUM(1),
502 LWORK_ZUNGBR_P_NN = INT( CDUM(1) )
504 CALL ZUNGBR( 'Q', M, M, N, CDUM(1), M, CDUM(1), CDUM(1),
506 LWORK_ZUNGBR_Q_MM = INT( CDUM(1) )
508 CALL ZUNGLQ( M, N, M, CDUM(1), M, CDUM(1), CDUM(1),
510 LWORK_ZUNGLQ_MN = INT( CDUM(1) )
512 CALL ZUNGLQ( N, N, M, CDUM(1), N, CDUM(1), CDUM(1),
514 LWORK_ZUNGLQ_NN = INT( CDUM(1) )
516 CALL ZUNMBR( 'P', 'R', 'C', M, M, M, CDUM(1), M, CDUM(1),
517 $ CDUM(1), M, CDUM(1), -1, IERR )
518 LWORK_ZUNMBR_PRC_MM = INT( CDUM(1) )
520 CALL ZUNMBR( 'P', 'R', 'C', M, N, M, CDUM(1), M, CDUM(1),
521 $ CDUM(1), M, CDUM(1), -1, IERR )
522 LWORK_ZUNMBR_PRC_MN = INT( CDUM(1) )
524 CALL ZUNMBR( 'P', 'R', 'C', N, N, M, CDUM(1), N, CDUM(1),
525 $ CDUM(1), N, CDUM(1), -1, IERR )
526 LWORK_ZUNMBR_PRC_NN = INT( CDUM(1) )
528 CALL ZUNMBR( 'Q', 'L', 'N', M, M, M, CDUM(1), M, CDUM(1),
529 $ CDUM(1), M, CDUM(1), -1, IERR )
530 LWORK_ZUNMBR_QLN_MM = INT( CDUM(1) )
532 IF( N.GE.MNTHR1 ) THEN
535 * Path 1t (N >> M, JOBZ='N')
537 MAXWRK = M + LWORK_ZGELQF_MN
538 MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZGEBRD_MM )
540 ELSE IF( WNTQO ) THEN
542 * Path 2t (N >> M, JOBZ='O')
544 WRKBL = M + LWORK_ZGELQF_MN
545 WRKBL = MAX( WRKBL, M + LWORK_ZUNGLQ_MN )
546 WRKBL = MAX( WRKBL, 2*M + LWORK_ZGEBRD_MM )
547 WRKBL = MAX( WRKBL, 2*M + LWORK_ZUNMBR_QLN_MM )
548 WRKBL = MAX( WRKBL, 2*M + LWORK_ZUNMBR_PRC_MM )
549 MAXWRK = M*N + M*M + WRKBL
551 ELSE IF( WNTQS ) THEN
553 * Path 3t (N >> M, JOBZ='S')
555 WRKBL = M + LWORK_ZGELQF_MN
556 WRKBL = MAX( WRKBL, M + LWORK_ZUNGLQ_MN )
557 WRKBL = MAX( WRKBL, 2*M + LWORK_ZGEBRD_MM )
558 WRKBL = MAX( WRKBL, 2*M + LWORK_ZUNMBR_QLN_MM )
559 WRKBL = MAX( WRKBL, 2*M + LWORK_ZUNMBR_PRC_MM )
562 ELSE IF( WNTQA ) THEN
564 * Path 4t (N >> M, JOBZ='A')
566 WRKBL = M + LWORK_ZGELQF_MN
567 WRKBL = MAX( WRKBL, M + LWORK_ZUNGLQ_NN )
568 WRKBL = MAX( WRKBL, 2*M + LWORK_ZGEBRD_MM )
569 WRKBL = MAX( WRKBL, 2*M + LWORK_ZUNMBR_QLN_MM )
570 WRKBL = MAX( WRKBL, 2*M + LWORK_ZUNMBR_PRC_MM )
572 MINWRK = M*M + MAX( 3*M, M + N )
574 ELSE IF( N.GE.MNTHR2 ) THEN
576 * Path 5t (N >> M, but not as much as MNTHR1)
578 MAXWRK = 2*M + LWORK_ZGEBRD_MN
581 * Path 5to (N >> M, JOBZ='O')
582 MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNGBR_Q_MM )
583 MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNGBR_P_MN )
584 MAXWRK = MAXWRK + M*N
585 MINWRK = MINWRK + M*M
586 ELSE IF( WNTQS ) THEN
587 * Path 5ts (N >> M, JOBZ='S')
588 MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNGBR_Q_MM )
589 MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNGBR_P_MN )
590 ELSE IF( WNTQA ) THEN
591 * Path 5ta (N >> M, JOBZ='A')
592 MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNGBR_Q_MM )
593 MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNGBR_P_NN )
597 * Path 6t (N > M, but not much larger)
599 MAXWRK = 2*M + LWORK_ZGEBRD_MN
602 * Path 6to (N > M, JOBZ='O')
603 MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNMBR_QLN_MM )
604 MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNMBR_PRC_MN )
605 MAXWRK = MAXWRK + M*N
606 MINWRK = MINWRK + M*M
607 ELSE IF( WNTQS ) THEN
608 * Path 6ts (N > M, JOBZ='S')
609 MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNMBR_QLN_MM )
610 MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNMBR_PRC_MN )
611 ELSE IF( WNTQA ) THEN
612 * Path 6ta (N > M, JOBZ='A')
613 MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNMBR_QLN_MM )
614 MAXWRK = MAX( MAXWRK, 2*M + LWORK_ZUNMBR_PRC_NN )
618 MAXWRK = MAX( MAXWRK, MINWRK )
622 IF( LWORK.LT.MINWRK .AND. .NOT. LQUERY ) THEN
628 CALL XERBLA( 'ZGESDD', -INFO )
630 ELSE IF( LQUERY ) THEN
634 * Quick return if possible
636 IF( M.EQ.0 .OR. N.EQ.0 ) THEN
640 * Get machine constants
643 SMLNUM = SQRT( DLAMCH( 'S' ) ) / EPS
644 BIGNUM = ONE / SMLNUM
646 * Scale A if max element outside range [SMLNUM,BIGNUM]
648 ANRM = ZLANGE( 'M', M, N, A, LDA, DUM )
650 IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
652 CALL ZLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, IERR )
653 ELSE IF( ANRM.GT.BIGNUM ) THEN
655 CALL ZLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, IERR )
660 * A has at least as many rows as columns. If A has sufficiently
661 * more rows than columns, first reduce using the QR
662 * decomposition (if sufficient workspace available)
664 IF( M.GE.MNTHR1 ) THEN
668 * Path 1 (M >> N, JOBZ='N')
669 * No singular vectors to be computed
675 * CWorkspace: need N [tau] + N [work]
676 * CWorkspace: prefer N [tau] + N*NB [work]
679 CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
680 $ LWORK-NWORK+1, IERR )
684 CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO, A( 2, 1 ),
691 * Bidiagonalize R in A
692 * CWorkspace: need 2*N [tauq, taup] + N [work]
693 * CWorkspace: prefer 2*N [tauq, taup] + 2*N*NB [work]
694 * RWorkspace: need N [e]
696 CALL ZGEBRD( N, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
697 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
701 * Perform bidiagonal SVD, compute singular values only
703 * RWorkspace: need N [e] + BDSPAC
705 CALL DBDSDC( 'U', 'N', N, S, RWORK( IE ), DUM,1,DUM,1,
706 $ DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
708 ELSE IF( WNTQO ) THEN
710 * Path 2 (M >> N, JOBZ='O')
711 * N left singular vectors to be overwritten on A and
712 * N right singular vectors to be computed in VT
720 IF( LWORK .GE. M*N + N*N + 3*N ) THEN
726 LDWRKR = ( LWORK - N*N - 3*N ) / N
732 * CWorkspace: need N*N [U] + N*N [R] + N [tau] + N [work]
733 * CWorkspace: prefer N*N [U] + N*N [R] + N [tau] + N*NB [work]
736 CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
737 $ LWORK-NWORK+1, IERR )
739 * Copy R to WORK( IR ), zeroing out below it
741 CALL ZLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )
742 CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO, WORK( IR+1 ),
746 * CWorkspace: need N*N [U] + N*N [R] + N [tau] + N [work]
747 * CWorkspace: prefer N*N [U] + N*N [R] + N [tau] + N*NB [work]
750 CALL ZUNGQR( M, N, N, A, LDA, WORK( ITAU ),
751 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
757 * Bidiagonalize R in WORK(IR)
758 * CWorkspace: need N*N [U] + N*N [R] + 2*N [tauq, taup] + N [work]
759 * CWorkspace: prefer N*N [U] + N*N [R] + 2*N [tauq, taup] + 2*N*NB [work]
760 * RWorkspace: need N [e]
762 CALL ZGEBRD( N, N, WORK( IR ), LDWRKR, S, RWORK( IE ),
763 $ WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
764 $ LWORK-NWORK+1, IERR )
766 * Perform bidiagonal SVD, computing left singular vectors
767 * of R in WORK(IRU) and computing right singular vectors
770 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT] + BDSPAC
775 CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
776 $ N, RWORK( IRVT ), N, DUM, IDUM,
777 $ RWORK( NRWORK ), IWORK, INFO )
779 * Copy real matrix RWORK(IRU) to complex matrix WORK(IU)
780 * Overwrite WORK(IU) by the left singular vectors of R
781 * CWorkspace: need N*N [U] + N*N [R] + 2*N [tauq, taup] + N [work]
782 * CWorkspace: prefer N*N [U] + N*N [R] + 2*N [tauq, taup] + N*NB [work]
785 CALL ZLACP2( 'F', N, N, RWORK( IRU ), N, WORK( IU ),
787 CALL ZUNMBR( 'Q', 'L', 'N', N, N, N, WORK( IR ), LDWRKR,
788 $ WORK( ITAUQ ), WORK( IU ), LDWRKU,
789 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
791 * Copy real matrix RWORK(IRVT) to complex matrix VT
792 * Overwrite VT by the right singular vectors of R
793 * CWorkspace: need N*N [U] + N*N [R] + 2*N [tauq, taup] + N [work]
794 * CWorkspace: prefer N*N [U] + N*N [R] + 2*N [tauq, taup] + N*NB [work]
797 CALL ZLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
798 CALL ZUNMBR( 'P', 'R', 'C', N, N, N, WORK( IR ), LDWRKR,
799 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
800 $ LWORK-NWORK+1, IERR )
802 * Multiply Q in A by left singular vectors of R in
803 * WORK(IU), storing result in WORK(IR) and copying to A
804 * CWorkspace: need N*N [U] + N*N [R]
805 * CWorkspace: prefer N*N [U] + M*N [R]
808 DO 10 I = 1, M, LDWRKR
809 CHUNK = MIN( M-I+1, LDWRKR )
810 CALL ZGEMM( 'N', 'N', CHUNK, N, N, CONE, A( I, 1 ),
811 $ LDA, WORK( IU ), LDWRKU, CZERO,
812 $ WORK( IR ), LDWRKR )
813 CALL ZLACPY( 'F', CHUNK, N, WORK( IR ), LDWRKR,
817 ELSE IF( WNTQS ) THEN
819 * Path 3 (M >> N, JOBZ='S')
820 * N left singular vectors to be computed in U and
821 * N right singular vectors to be computed in VT
832 * CWorkspace: need N*N [R] + N [tau] + N [work]
833 * CWorkspace: prefer N*N [R] + N [tau] + N*NB [work]
836 CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
837 $ LWORK-NWORK+1, IERR )
839 * Copy R to WORK(IR), zeroing out below it
841 CALL ZLACPY( 'U', N, N, A, LDA, WORK( IR ), LDWRKR )
842 CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO, WORK( IR+1 ),
846 * CWorkspace: need N*N [R] + N [tau] + N [work]
847 * CWorkspace: prefer N*N [R] + N [tau] + N*NB [work]
850 CALL ZUNGQR( M, N, N, A, LDA, WORK( ITAU ),
851 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
857 * Bidiagonalize R in WORK(IR)
858 * CWorkspace: need N*N [R] + 2*N [tauq, taup] + N [work]
859 * CWorkspace: prefer N*N [R] + 2*N [tauq, taup] + 2*N*NB [work]
860 * RWorkspace: need N [e]
862 CALL ZGEBRD( N, N, WORK( IR ), LDWRKR, S, RWORK( IE ),
863 $ WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
864 $ LWORK-NWORK+1, IERR )
866 * Perform bidiagonal SVD, computing left singular vectors
867 * of bidiagonal matrix in RWORK(IRU) and computing right
868 * singular vectors of bidiagonal matrix in RWORK(IRVT)
870 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT] + BDSPAC
875 CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
876 $ N, RWORK( IRVT ), N, DUM, IDUM,
877 $ RWORK( NRWORK ), IWORK, INFO )
879 * Copy real matrix RWORK(IRU) to complex matrix U
880 * Overwrite U by left singular vectors of R
881 * CWorkspace: need N*N [R] + 2*N [tauq, taup] + N [work]
882 * CWorkspace: prefer N*N [R] + 2*N [tauq, taup] + N*NB [work]
885 CALL ZLACP2( 'F', N, N, RWORK( IRU ), N, U, LDU )
886 CALL ZUNMBR( 'Q', 'L', 'N', N, N, N, WORK( IR ), LDWRKR,
887 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
888 $ LWORK-NWORK+1, IERR )
890 * Copy real matrix RWORK(IRVT) to complex matrix VT
891 * Overwrite VT by right singular vectors of R
892 * CWorkspace: need N*N [R] + 2*N [tauq, taup] + N [work]
893 * CWorkspace: prefer N*N [R] + 2*N [tauq, taup] + N*NB [work]
896 CALL ZLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
897 CALL ZUNMBR( 'P', 'R', 'C', N, N, N, WORK( IR ), LDWRKR,
898 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
899 $ LWORK-NWORK+1, IERR )
901 * Multiply Q in A by left singular vectors of R in
902 * WORK(IR), storing result in U
903 * CWorkspace: need N*N [R]
906 CALL ZLACPY( 'F', N, N, U, LDU, WORK( IR ), LDWRKR )
907 CALL ZGEMM( 'N', 'N', M, N, N, CONE, A, LDA, WORK( IR ),
908 $ LDWRKR, CZERO, U, LDU )
910 ELSE IF( WNTQA ) THEN
912 * Path 4 (M >> N, JOBZ='A')
913 * M left singular vectors to be computed in U and
914 * N right singular vectors to be computed in VT
924 * Compute A=Q*R, copying result to U
925 * CWorkspace: need N*N [U] + N [tau] + N [work]
926 * CWorkspace: prefer N*N [U] + N [tau] + N*NB [work]
929 CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
930 $ LWORK-NWORK+1, IERR )
931 CALL ZLACPY( 'L', M, N, A, LDA, U, LDU )
934 * CWorkspace: need N*N [U] + N [tau] + M [work]
935 * CWorkspace: prefer N*N [U] + N [tau] + M*NB [work]
938 CALL ZUNGQR( M, M, N, U, LDU, WORK( ITAU ),
939 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
941 * Produce R in A, zeroing out below it
943 CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO, A( 2, 1 ),
950 * Bidiagonalize R in A
951 * CWorkspace: need N*N [U] + 2*N [tauq, taup] + N [work]
952 * CWorkspace: prefer N*N [U] + 2*N [tauq, taup] + 2*N*NB [work]
953 * RWorkspace: need N [e]
955 CALL ZGEBRD( N, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
956 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
962 * Perform bidiagonal SVD, computing left singular vectors
963 * of bidiagonal matrix in RWORK(IRU) and computing right
964 * singular vectors of bidiagonal matrix in RWORK(IRVT)
966 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT] + BDSPAC
968 CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
969 $ N, RWORK( IRVT ), N, DUM, IDUM,
970 $ RWORK( NRWORK ), IWORK, INFO )
972 * Copy real matrix RWORK(IRU) to complex matrix WORK(IU)
973 * Overwrite WORK(IU) by left singular vectors of R
974 * CWorkspace: need N*N [U] + 2*N [tauq, taup] + N [work]
975 * CWorkspace: prefer N*N [U] + 2*N [tauq, taup] + N*NB [work]
978 CALL ZLACP2( 'F', N, N, RWORK( IRU ), N, WORK( IU ),
980 CALL ZUNMBR( 'Q', 'L', 'N', N, N, N, A, LDA,
981 $ WORK( ITAUQ ), WORK( IU ), LDWRKU,
982 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
984 * Copy real matrix RWORK(IRVT) to complex matrix VT
985 * Overwrite VT by right singular vectors of R
986 * CWorkspace: need N*N [U] + 2*N [tauq, taup] + N [work]
987 * CWorkspace: prefer N*N [U] + 2*N [tauq, taup] + N*NB [work]
990 CALL ZLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
991 CALL ZUNMBR( 'P', 'R', 'C', N, N, N, A, LDA,
992 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
993 $ LWORK-NWORK+1, IERR )
995 * Multiply Q in U by left singular vectors of R in
996 * WORK(IU), storing result in A
997 * CWorkspace: need N*N [U]
1000 CALL ZGEMM( 'N', 'N', M, N, N, CONE, U, LDU, WORK( IU ),
1001 $ LDWRKU, CZERO, A, LDA )
1003 * Copy left singular vectors of A from A to U
1005 CALL ZLACPY( 'F', M, N, A, LDA, U, LDU )
1009 ELSE IF( M.GE.MNTHR2 ) THEN
1011 * MNTHR2 <= M < MNTHR1
1013 * Path 5 (M >> N, but not as much as MNTHR1)
1014 * Reduce to bidiagonal form without QR decomposition, use
1015 * ZUNGBR and matrix multiplication to compute singular vectors
1024 * CWorkspace: need 2*N [tauq, taup] + M [work]
1025 * CWorkspace: prefer 2*N [tauq, taup] + (M+N)*NB [work]
1026 * RWorkspace: need N [e]
1028 CALL ZGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
1029 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
1033 * Path 5n (M >> N, JOBZ='N')
1034 * Compute singular values only
1035 * CWorkspace: need 0
1036 * RWorkspace: need N [e] + BDSPAC
1038 CALL DBDSDC( 'U', 'N', N, S, RWORK( IE ), DUM, 1,DUM,1,
1039 $ DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
1040 ELSE IF( WNTQO ) THEN
1046 * Path 5o (M >> N, JOBZ='O')
1047 * Copy A to VT, generate P**H
1048 * CWorkspace: need 2*N [tauq, taup] + N [work]
1049 * CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
1050 * RWorkspace: need 0
1052 CALL ZLACPY( 'U', N, N, A, LDA, VT, LDVT )
1053 CALL ZUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
1054 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1057 * CWorkspace: need 2*N [tauq, taup] + N [work]
1058 * CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
1059 * RWorkspace: need 0
1061 CALL ZUNGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
1062 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1064 IF( LWORK .GE. M*N + 3*N ) THEN
1066 * WORK( IU ) is M by N
1071 * WORK(IU) is LDWRKU by N
1073 LDWRKU = ( LWORK - 3*N ) / N
1075 NWORK = IU + LDWRKU*N
1077 * Perform bidiagonal SVD, computing left singular vectors
1078 * of bidiagonal matrix in RWORK(IRU) and computing right
1079 * singular vectors of bidiagonal matrix in RWORK(IRVT)
1080 * CWorkspace: need 0
1081 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT] + BDSPAC
1083 CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
1084 $ N, RWORK( IRVT ), N, DUM, IDUM,
1085 $ RWORK( NRWORK ), IWORK, INFO )
1087 * Multiply real matrix RWORK(IRVT) by P**H in VT,
1088 * storing the result in WORK(IU), copying to VT
1089 * CWorkspace: need 2*N [tauq, taup] + N*N [U]
1090 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT] + 2*N*N [rwork]
1092 CALL ZLARCM( N, N, RWORK( IRVT ), N, VT, LDVT,
1093 $ WORK( IU ), LDWRKU, RWORK( NRWORK ) )
1094 CALL ZLACPY( 'F', N, N, WORK( IU ), LDWRKU, VT, LDVT )
1096 * Multiply Q in A by real matrix RWORK(IRU), storing the
1097 * result in WORK(IU), copying to A
1098 * CWorkspace: need 2*N [tauq, taup] + N*N [U]
1099 * CWorkspace: prefer 2*N [tauq, taup] + M*N [U]
1100 * RWorkspace: need N [e] + N*N [RU] + 2*N*N [rwork]
1101 * RWorkspace: prefer N [e] + N*N [RU] + 2*M*N [rwork] < N + 5*N*N since M < 2*N here
1104 DO 20 I = 1, M, LDWRKU
1105 CHUNK = MIN( M-I+1, LDWRKU )
1106 CALL ZLACRM( CHUNK, N, A( I, 1 ), LDA, RWORK( IRU ),
1107 $ N, WORK( IU ), LDWRKU, RWORK( NRWORK ) )
1108 CALL ZLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,
1112 ELSE IF( WNTQS ) THEN
1114 * Path 5s (M >> N, JOBZ='S')
1115 * Copy A to VT, generate P**H
1116 * CWorkspace: need 2*N [tauq, taup] + N [work]
1117 * CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
1118 * RWorkspace: need 0
1120 CALL ZLACPY( 'U', N, N, A, LDA, VT, LDVT )
1121 CALL ZUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
1122 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1124 * Copy A to U, generate Q
1125 * CWorkspace: need 2*N [tauq, taup] + N [work]
1126 * CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
1127 * RWorkspace: need 0
1129 CALL ZLACPY( 'L', M, N, A, LDA, U, LDU )
1130 CALL ZUNGBR( 'Q', M, N, N, U, LDU, WORK( ITAUQ ),
1131 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1133 * Perform bidiagonal SVD, computing left singular vectors
1134 * of bidiagonal matrix in RWORK(IRU) and computing right
1135 * singular vectors of bidiagonal matrix in RWORK(IRVT)
1136 * CWorkspace: need 0
1137 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT] + BDSPAC
1142 CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
1143 $ N, RWORK( IRVT ), N, DUM, IDUM,
1144 $ RWORK( NRWORK ), IWORK, INFO )
1146 * Multiply real matrix RWORK(IRVT) by P**H in VT,
1147 * storing the result in A, copying to VT
1148 * CWorkspace: need 0
1149 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT] + 2*N*N [rwork]
1151 CALL ZLARCM( N, N, RWORK( IRVT ), N, VT, LDVT, A, LDA,
1153 CALL ZLACPY( 'F', N, N, A, LDA, VT, LDVT )
1155 * Multiply Q in U by real matrix RWORK(IRU), storing the
1156 * result in A, copying to U
1157 * CWorkspace: need 0
1158 * RWorkspace: need N [e] + N*N [RU] + 2*M*N [rwork] < N + 5*N*N since M < 2*N here
1161 CALL ZLACRM( M, N, U, LDU, RWORK( IRU ), N, A, LDA,
1163 CALL ZLACPY( 'F', M, N, A, LDA, U, LDU )
1166 * Path 5a (M >> N, JOBZ='A')
1167 * Copy A to VT, generate P**H
1168 * CWorkspace: need 2*N [tauq, taup] + N [work]
1169 * CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
1170 * RWorkspace: need 0
1172 CALL ZLACPY( 'U', N, N, A, LDA, VT, LDVT )
1173 CALL ZUNGBR( 'P', N, N, N, VT, LDVT, WORK( ITAUP ),
1174 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1176 * Copy A to U, generate Q
1177 * CWorkspace: need 2*N [tauq, taup] + M [work]
1178 * CWorkspace: prefer 2*N [tauq, taup] + M*NB [work]
1179 * RWorkspace: need 0
1181 CALL ZLACPY( 'L', M, N, A, LDA, U, LDU )
1182 CALL ZUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
1183 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1185 * Perform bidiagonal SVD, computing left singular vectors
1186 * of bidiagonal matrix in RWORK(IRU) and computing right
1187 * singular vectors of bidiagonal matrix in RWORK(IRVT)
1188 * CWorkspace: need 0
1189 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT] + BDSPAC
1194 CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
1195 $ N, RWORK( IRVT ), N, DUM, IDUM,
1196 $ RWORK( NRWORK ), IWORK, INFO )
1198 * Multiply real matrix RWORK(IRVT) by P**H in VT,
1199 * storing the result in A, copying to VT
1200 * CWorkspace: need 0
1201 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT] + 2*N*N [rwork]
1203 CALL ZLARCM( N, N, RWORK( IRVT ), N, VT, LDVT, A, LDA,
1205 CALL ZLACPY( 'F', N, N, A, LDA, VT, LDVT )
1207 * Multiply Q in U by real matrix RWORK(IRU), storing the
1208 * result in A, copying to U
1209 * CWorkspace: need 0
1210 * RWorkspace: need N [e] + N*N [RU] + 2*M*N [rwork] < N + 5*N*N since M < 2*N here
1213 CALL ZLACRM( M, N, U, LDU, RWORK( IRU ), N, A, LDA,
1215 CALL ZLACPY( 'F', M, N, A, LDA, U, LDU )
1222 * Path 6 (M >= N, but not much larger)
1223 * Reduce to bidiagonal form without QR decomposition
1224 * Use ZUNMBR to compute singular vectors
1233 * CWorkspace: need 2*N [tauq, taup] + M [work]
1234 * CWorkspace: prefer 2*N [tauq, taup] + (M+N)*NB [work]
1235 * RWorkspace: need N [e]
1237 CALL ZGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
1238 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
1242 * Path 6n (M >= N, JOBZ='N')
1243 * Compute singular values only
1244 * CWorkspace: need 0
1245 * RWorkspace: need N [e] + BDSPAC
1247 CALL DBDSDC( 'U', 'N', N, S, RWORK( IE ), DUM,1,DUM,1,
1248 $ DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
1249 ELSE IF( WNTQO ) THEN
1254 IF( LWORK .GE. M*N + 3*N ) THEN
1256 * WORK( IU ) is M by N
1261 * WORK( IU ) is LDWRKU by N
1263 LDWRKU = ( LWORK - 3*N ) / N
1265 NWORK = IU + LDWRKU*N
1267 * Path 6o (M >= N, JOBZ='O')
1268 * Perform bidiagonal SVD, computing left singular vectors
1269 * of bidiagonal matrix in RWORK(IRU) and computing right
1270 * singular vectors of bidiagonal matrix in RWORK(IRVT)
1271 * CWorkspace: need 0
1272 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT] + BDSPAC
1274 CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
1275 $ N, RWORK( IRVT ), N, DUM, IDUM,
1276 $ RWORK( NRWORK ), IWORK, INFO )
1278 * Copy real matrix RWORK(IRVT) to complex matrix VT
1279 * Overwrite VT by right singular vectors of A
1280 * CWorkspace: need 2*N [tauq, taup] + N*N [U] + N [work]
1281 * CWorkspace: prefer 2*N [tauq, taup] + N*N [U] + N*NB [work]
1282 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT]
1284 CALL ZLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
1285 CALL ZUNMBR( 'P', 'R', 'C', N, N, N, A, LDA,
1286 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
1287 $ LWORK-NWORK+1, IERR )
1289 IF( LWORK .GE. M*N + 3*N ) THEN
1292 * Copy real matrix RWORK(IRU) to complex matrix WORK(IU)
1293 * Overwrite WORK(IU) by left singular vectors of A, copying
1295 * CWorkspace: need 2*N [tauq, taup] + M*N [U] + N [work]
1296 * CWorkspace: prefer 2*N [tauq, taup] + M*N [U] + N*NB [work]
1297 * RWorkspace: need N [e] + N*N [RU]
1299 CALL ZLASET( 'F', M, N, CZERO, CZERO, WORK( IU ),
1301 CALL ZLACP2( 'F', N, N, RWORK( IRU ), N, WORK( IU ),
1303 CALL ZUNMBR( 'Q', 'L', 'N', M, N, N, A, LDA,
1304 $ WORK( ITAUQ ), WORK( IU ), LDWRKU,
1305 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1306 CALL ZLACPY( 'F', M, N, WORK( IU ), LDWRKU, A, LDA )
1311 * CWorkspace: need 2*N [tauq, taup] + N*N [U] + N [work]
1312 * CWorkspace: prefer 2*N [tauq, taup] + N*N [U] + N*NB [work]
1313 * RWorkspace: need 0
1315 CALL ZUNGBR( 'Q', M, N, N, A, LDA, WORK( ITAUQ ),
1316 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1318 * Multiply Q in A by real matrix RWORK(IRU), storing the
1319 * result in WORK(IU), copying to A
1320 * CWorkspace: need 2*N [tauq, taup] + N*N [U]
1321 * CWorkspace: prefer 2*N [tauq, taup] + M*N [U]
1322 * RWorkspace: need N [e] + N*N [RU] + 2*N*N [rwork]
1323 * RWorkspace: prefer N [e] + N*N [RU] + 2*M*N [rwork] < N + 5*N*N since M < 2*N here
1326 DO 30 I = 1, M, LDWRKU
1327 CHUNK = MIN( M-I+1, LDWRKU )
1328 CALL ZLACRM( CHUNK, N, A( I, 1 ), LDA,
1329 $ RWORK( IRU ), N, WORK( IU ), LDWRKU,
1331 CALL ZLACPY( 'F', CHUNK, N, WORK( IU ), LDWRKU,
1336 ELSE IF( WNTQS ) THEN
1338 * Path 6s (M >= N, JOBZ='S')
1339 * Perform bidiagonal SVD, computing left singular vectors
1340 * of bidiagonal matrix in RWORK(IRU) and computing right
1341 * singular vectors of bidiagonal matrix in RWORK(IRVT)
1342 * CWorkspace: need 0
1343 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT] + BDSPAC
1348 CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
1349 $ N, RWORK( IRVT ), N, DUM, IDUM,
1350 $ RWORK( NRWORK ), IWORK, INFO )
1352 * Copy real matrix RWORK(IRU) to complex matrix U
1353 * Overwrite U by left singular vectors of A
1354 * CWorkspace: need 2*N [tauq, taup] + N [work]
1355 * CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
1356 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT]
1358 CALL ZLASET( 'F', M, N, CZERO, CZERO, U, LDU )
1359 CALL ZLACP2( 'F', N, N, RWORK( IRU ), N, U, LDU )
1360 CALL ZUNMBR( 'Q', 'L', 'N', M, N, N, A, LDA,
1361 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
1362 $ LWORK-NWORK+1, IERR )
1364 * Copy real matrix RWORK(IRVT) to complex matrix VT
1365 * Overwrite VT by right singular vectors of A
1366 * CWorkspace: need 2*N [tauq, taup] + N [work]
1367 * CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
1368 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT]
1370 CALL ZLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
1371 CALL ZUNMBR( 'P', 'R', 'C', N, N, N, A, LDA,
1372 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
1373 $ LWORK-NWORK+1, IERR )
1376 * Path 6a (M >= N, JOBZ='A')
1377 * Perform bidiagonal SVD, computing left singular vectors
1378 * of bidiagonal matrix in RWORK(IRU) and computing right
1379 * singular vectors of bidiagonal matrix in RWORK(IRVT)
1380 * CWorkspace: need 0
1381 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT] + BDSPAC
1386 CALL DBDSDC( 'U', 'I', N, S, RWORK( IE ), RWORK( IRU ),
1387 $ N, RWORK( IRVT ), N, DUM, IDUM,
1388 $ RWORK( NRWORK ), IWORK, INFO )
1390 * Set the right corner of U to identity matrix
1392 CALL ZLASET( 'F', M, M, CZERO, CZERO, U, LDU )
1394 CALL ZLASET( 'F', M-N, M-N, CZERO, CONE,
1395 $ U( N+1, N+1 ), LDU )
1398 * Copy real matrix RWORK(IRU) to complex matrix U
1399 * Overwrite U by left singular vectors of A
1400 * CWorkspace: need 2*N [tauq, taup] + M [work]
1401 * CWorkspace: prefer 2*N [tauq, taup] + M*NB [work]
1402 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT]
1404 CALL ZLACP2( 'F', N, N, RWORK( IRU ), N, U, LDU )
1405 CALL ZUNMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
1406 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
1407 $ LWORK-NWORK+1, IERR )
1409 * Copy real matrix RWORK(IRVT) to complex matrix VT
1410 * Overwrite VT by right singular vectors of A
1411 * CWorkspace: need 2*N [tauq, taup] + N [work]
1412 * CWorkspace: prefer 2*N [tauq, taup] + N*NB [work]
1413 * RWorkspace: need N [e] + N*N [RU] + N*N [RVT]
1415 CALL ZLACP2( 'F', N, N, RWORK( IRVT ), N, VT, LDVT )
1416 CALL ZUNMBR( 'P', 'R', 'C', N, N, N, A, LDA,
1417 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
1418 $ LWORK-NWORK+1, IERR )
1425 * A has more columns than rows. If A has sufficiently more
1426 * columns than rows, first reduce using the LQ decomposition (if
1427 * sufficient workspace available)
1429 IF( N.GE.MNTHR1 ) THEN
1433 * Path 1t (N >> M, JOBZ='N')
1434 * No singular vectors to be computed
1440 * CWorkspace: need M [tau] + M [work]
1441 * CWorkspace: prefer M [tau] + M*NB [work]
1442 * RWorkspace: need 0
1444 CALL ZGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
1445 $ LWORK-NWORK+1, IERR )
1449 CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO, A( 1, 2 ),
1456 * Bidiagonalize L in A
1457 * CWorkspace: need 2*M [tauq, taup] + M [work]
1458 * CWorkspace: prefer 2*M [tauq, taup] + 2*M*NB [work]
1459 * RWorkspace: need M [e]
1461 CALL ZGEBRD( M, M, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
1462 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
1466 * Perform bidiagonal SVD, compute singular values only
1467 * CWorkspace: need 0
1468 * RWorkspace: need M [e] + BDSPAC
1470 CALL DBDSDC( 'U', 'N', M, S, RWORK( IE ), DUM,1,DUM,1,
1471 $ DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
1473 ELSE IF( WNTQO ) THEN
1475 * Path 2t (N >> M, JOBZ='O')
1476 * M right singular vectors to be overwritten on A and
1477 * M left singular vectors to be computed in U
1482 * WORK(IVT) is M by M
1485 IF( LWORK .GE. M*N + M*M + 3*M ) THEN
1493 * WORK(IL) is M by CHUNK
1496 CHUNK = ( LWORK - M*M - 3*M ) / M
1498 ITAU = IL + LDWRKL*CHUNK
1502 * CWorkspace: need M*M [VT] + M*M [L] + M [tau] + M [work]
1503 * CWorkspace: prefer M*M [VT] + M*M [L] + M [tau] + M*NB [work]
1504 * RWorkspace: need 0
1506 CALL ZGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
1507 $ LWORK-NWORK+1, IERR )
1509 * Copy L to WORK(IL), zeroing about above it
1511 CALL ZLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWRKL )
1512 CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO,
1513 $ WORK( IL+LDWRKL ), LDWRKL )
1516 * CWorkspace: need M*M [VT] + M*M [L] + M [tau] + M [work]
1517 * CWorkspace: prefer M*M [VT] + M*M [L] + M [tau] + M*NB [work]
1518 * RWorkspace: need 0
1520 CALL ZUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
1521 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1527 * Bidiagonalize L in WORK(IL)
1528 * CWorkspace: need M*M [VT] + M*M [L] + 2*M [tauq, taup] + M [work]
1529 * CWorkspace: prefer M*M [VT] + M*M [L] + 2*M [tauq, taup] + 2*M*NB [work]
1530 * RWorkspace: need M [e]
1532 CALL ZGEBRD( M, M, WORK( IL ), LDWRKL, S, RWORK( IE ),
1533 $ WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
1534 $ LWORK-NWORK+1, IERR )
1536 * Perform bidiagonal SVD, computing left singular vectors
1537 * of bidiagonal matrix in RWORK(IRU) and computing right
1538 * singular vectors of bidiagonal matrix in RWORK(IRVT)
1539 * CWorkspace: need 0
1540 * RWorkspace: need M [e] + M*M [RU] + M*M [RVT] + BDSPAC
1545 CALL DBDSDC( 'U', 'I', M, S, RWORK( IE ), RWORK( IRU ),
1546 $ M, RWORK( IRVT ), M, DUM, IDUM,
1547 $ RWORK( NRWORK ), IWORK, INFO )
1549 * Copy real matrix RWORK(IRU) to complex matrix WORK(IU)
1550 * Overwrite WORK(IU) by the left singular vectors of L
1551 * CWorkspace: need M*M [VT] + M*M [L] + 2*M [tauq, taup] + M [work]
1552 * CWorkspace: prefer M*M [VT] + M*M [L] + 2*M [tauq, taup] + M*NB [work]
1553 * RWorkspace: need 0
1555 CALL ZLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
1556 CALL ZUNMBR( 'Q', 'L', 'N', M, M, M, WORK( IL ), LDWRKL,
1557 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
1558 $ LWORK-NWORK+1, IERR )
1560 * Copy real matrix RWORK(IRVT) to complex matrix WORK(IVT)
1561 * Overwrite WORK(IVT) by the right singular vectors of L
1562 * CWorkspace: need M*M [VT] + M*M [L] + 2*M [tauq, taup] + M [work]
1563 * CWorkspace: prefer M*M [VT] + M*M [L] + 2*M [tauq, taup] + M*NB [work]
1564 * RWorkspace: need 0
1566 CALL ZLACP2( 'F', M, M, RWORK( IRVT ), M, WORK( IVT ),
1568 CALL ZUNMBR( 'P', 'R', 'C', M, M, M, WORK( IL ), LDWRKL,
1569 $ WORK( ITAUP ), WORK( IVT ), LDWKVT,
1570 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1572 * Multiply right singular vectors of L in WORK(IL) by Q
1573 * in A, storing result in WORK(IL) and copying to A
1574 * CWorkspace: need M*M [VT] + M*M [L]
1575 * CWorkspace: prefer M*M [VT] + M*N [L]
1576 * RWorkspace: need 0
1578 DO 40 I = 1, N, CHUNK
1579 BLK = MIN( N-I+1, CHUNK )
1580 CALL ZGEMM( 'N', 'N', M, BLK, M, CONE, WORK( IVT ), M,
1581 $ A( 1, I ), LDA, CZERO, WORK( IL ),
1583 CALL ZLACPY( 'F', M, BLK, WORK( IL ), LDWRKL,
1587 ELSE IF( WNTQS ) THEN
1589 * Path 3t (N >> M, JOBZ='S')
1590 * M right singular vectors to be computed in VT and
1591 * M left singular vectors to be computed in U
1595 * WORK(IL) is M by M
1598 ITAU = IL + LDWRKL*M
1602 * CWorkspace: need M*M [L] + M [tau] + M [work]
1603 * CWorkspace: prefer M*M [L] + M [tau] + M*NB [work]
1604 * RWorkspace: need 0
1606 CALL ZGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
1607 $ LWORK-NWORK+1, IERR )
1609 * Copy L to WORK(IL), zeroing out above it
1611 CALL ZLACPY( 'L', M, M, A, LDA, WORK( IL ), LDWRKL )
1612 CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO,
1613 $ WORK( IL+LDWRKL ), LDWRKL )
1616 * CWorkspace: need M*M [L] + M [tau] + M [work]
1617 * CWorkspace: prefer M*M [L] + M [tau] + M*NB [work]
1618 * RWorkspace: need 0
1620 CALL ZUNGLQ( M, N, M, A, LDA, WORK( ITAU ),
1621 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1627 * Bidiagonalize L in WORK(IL)
1628 * CWorkspace: need M*M [L] + 2*M [tauq, taup] + M [work]
1629 * CWorkspace: prefer M*M [L] + 2*M [tauq, taup] + 2*M*NB [work]
1630 * RWorkspace: need M [e]
1632 CALL ZGEBRD( M, M, WORK( IL ), LDWRKL, S, RWORK( IE ),
1633 $ WORK( ITAUQ ), WORK( ITAUP ), WORK( NWORK ),
1634 $ LWORK-NWORK+1, IERR )
1636 * Perform bidiagonal SVD, computing left singular vectors
1637 * of bidiagonal matrix in RWORK(IRU) and computing right
1638 * singular vectors of bidiagonal matrix in RWORK(IRVT)
1639 * CWorkspace: need 0
1640 * RWorkspace: need M [e] + M*M [RU] + M*M [RVT] + BDSPAC
1645 CALL DBDSDC( 'U', 'I', M, S, RWORK( IE ), RWORK( IRU ),
1646 $ M, RWORK( IRVT ), M, DUM, IDUM,
1647 $ RWORK( NRWORK ), IWORK, INFO )
1649 * Copy real matrix RWORK(IRU) to complex matrix U
1650 * Overwrite U by left singular vectors of L
1651 * CWorkspace: need M*M [L] + 2*M [tauq, taup] + M [work]
1652 * CWorkspace: prefer M*M [L] + 2*M [tauq, taup] + M*NB [work]
1653 * RWorkspace: need 0
1655 CALL ZLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
1656 CALL ZUNMBR( 'Q', 'L', 'N', M, M, M, WORK( IL ), LDWRKL,
1657 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
1658 $ LWORK-NWORK+1, IERR )
1660 * Copy real matrix RWORK(IRVT) to complex matrix VT
1661 * Overwrite VT by left singular vectors of L
1662 * CWorkspace: need M*M [L] + 2*M [tauq, taup] + M [work]
1663 * CWorkspace: prefer M*M [L] + 2*M [tauq, taup] + M*NB [work]
1664 * RWorkspace: need 0
1666 CALL ZLACP2( 'F', M, M, RWORK( IRVT ), M, VT, LDVT )
1667 CALL ZUNMBR( 'P', 'R', 'C', M, M, M, WORK( IL ), LDWRKL,
1668 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
1669 $ LWORK-NWORK+1, IERR )
1671 * Copy VT to WORK(IL), multiply right singular vectors of L
1672 * in WORK(IL) by Q in A, storing result in VT
1673 * CWorkspace: need M*M [L]
1674 * RWorkspace: need 0
1676 CALL ZLACPY( 'F', M, M, VT, LDVT, WORK( IL ), LDWRKL )
1677 CALL ZGEMM( 'N', 'N', M, N, M, CONE, WORK( IL ), LDWRKL,
1678 $ A, LDA, CZERO, VT, LDVT )
1680 ELSE IF( WNTQA ) THEN
1682 * Path 4t (N >> M, JOBZ='A')
1683 * N right singular vectors to be computed in VT and
1684 * M left singular vectors to be computed in U
1688 * WORK(IVT) is M by M
1691 ITAU = IVT + LDWKVT*M
1694 * Compute A=L*Q, copying result to VT
1695 * CWorkspace: need M*M [VT] + M [tau] + M [work]
1696 * CWorkspace: prefer M*M [VT] + M [tau] + M*NB [work]
1697 * RWorkspace: need 0
1699 CALL ZGELQF( M, N, A, LDA, WORK( ITAU ), WORK( NWORK ),
1700 $ LWORK-NWORK+1, IERR )
1701 CALL ZLACPY( 'U', M, N, A, LDA, VT, LDVT )
1704 * CWorkspace: need M*M [VT] + M [tau] + N [work]
1705 * CWorkspace: prefer M*M [VT] + M [tau] + N*NB [work]
1706 * RWorkspace: need 0
1708 CALL ZUNGLQ( N, N, M, VT, LDVT, WORK( ITAU ),
1709 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1711 * Produce L in A, zeroing out above it
1713 CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO, A( 1, 2 ),
1720 * Bidiagonalize L in A
1721 * CWorkspace: need M*M [VT] + 2*M [tauq, taup] + M [work]
1722 * CWorkspace: prefer M*M [VT] + 2*M [tauq, taup] + 2*M*NB [work]
1723 * RWorkspace: need M [e]
1725 CALL ZGEBRD( M, M, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
1726 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
1729 * Perform bidiagonal SVD, computing left singular vectors
1730 * of bidiagonal matrix in RWORK(IRU) and computing right
1731 * singular vectors of bidiagonal matrix in RWORK(IRVT)
1732 * CWorkspace: need 0
1733 * RWorkspace: need M [e] + M*M [RU] + M*M [RVT] + BDSPAC
1738 CALL DBDSDC( 'U', 'I', M, S, RWORK( IE ), RWORK( IRU ),
1739 $ M, RWORK( IRVT ), M, DUM, IDUM,
1740 $ RWORK( NRWORK ), IWORK, INFO )
1742 * Copy real matrix RWORK(IRU) to complex matrix U
1743 * Overwrite U by left singular vectors of L
1744 * CWorkspace: need M*M [VT] + 2*M [tauq, taup] + M [work]
1745 * CWorkspace: prefer M*M [VT] + 2*M [tauq, taup] + M*NB [work]
1746 * RWorkspace: need 0
1748 CALL ZLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
1749 CALL ZUNMBR( 'Q', 'L', 'N', M, M, M, A, LDA,
1750 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
1751 $ LWORK-NWORK+1, IERR )
1753 * Copy real matrix RWORK(IRVT) to complex matrix WORK(IVT)
1754 * Overwrite WORK(IVT) by right singular vectors of L
1755 * CWorkspace: need M*M [VT] + 2*M [tauq, taup] + M [work]
1756 * CWorkspace: prefer M*M [VT] + 2*M [tauq, taup] + M*NB [work]
1757 * RWorkspace: need 0
1759 CALL ZLACP2( 'F', M, M, RWORK( IRVT ), M, WORK( IVT ),
1761 CALL ZUNMBR( 'P', 'R', 'C', M, M, M, A, LDA,
1762 $ WORK( ITAUP ), WORK( IVT ), LDWKVT,
1763 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1765 * Multiply right singular vectors of L in WORK(IVT) by
1766 * Q in VT, storing result in A
1767 * CWorkspace: need M*M [VT]
1768 * RWorkspace: need 0
1770 CALL ZGEMM( 'N', 'N', M, N, M, CONE, WORK( IVT ), LDWKVT,
1771 $ VT, LDVT, CZERO, A, LDA )
1773 * Copy right singular vectors of A from A to VT
1775 CALL ZLACPY( 'F', M, N, A, LDA, VT, LDVT )
1779 ELSE IF( N.GE.MNTHR2 ) THEN
1781 * MNTHR2 <= N < MNTHR1
1783 * Path 5t (N >> M, but not as much as MNTHR1)
1784 * Reduce to bidiagonal form without QR decomposition, use
1785 * ZUNGBR and matrix multiplication to compute singular vectors
1794 * CWorkspace: need 2*M [tauq, taup] + N [work]
1795 * CWorkspace: prefer 2*M [tauq, taup] + (M+N)*NB [work]
1796 * RWorkspace: need M [e]
1798 CALL ZGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
1799 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
1804 * Path 5tn (N >> M, JOBZ='N')
1805 * Compute singular values only
1806 * CWorkspace: need 0
1807 * RWorkspace: need M [e] + BDSPAC
1809 CALL DBDSDC( 'L', 'N', M, S, RWORK( IE ), DUM,1,DUM,1,
1810 $ DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
1811 ELSE IF( WNTQO ) THEN
1817 * Path 5to (N >> M, JOBZ='O')
1818 * Copy A to U, generate Q
1819 * CWorkspace: need 2*M [tauq, taup] + M [work]
1820 * CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
1821 * RWorkspace: need 0
1823 CALL ZLACPY( 'L', M, M, A, LDA, U, LDU )
1824 CALL ZUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
1825 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1827 * Generate P**H in A
1828 * CWorkspace: need 2*M [tauq, taup] + M [work]
1829 * CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
1830 * RWorkspace: need 0
1832 CALL ZUNGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
1833 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1836 IF( LWORK .GE. M*N + 3*M ) THEN
1838 * WORK( IVT ) is M by N
1840 NWORK = IVT + LDWKVT*N
1844 * WORK( IVT ) is M by CHUNK
1846 CHUNK = ( LWORK - 3*M ) / M
1847 NWORK = IVT + LDWKVT*CHUNK
1850 * Perform bidiagonal SVD, computing left singular vectors
1851 * of bidiagonal matrix in RWORK(IRU) and computing right
1852 * singular vectors of bidiagonal matrix in RWORK(IRVT)
1853 * CWorkspace: need 0
1854 * RWorkspace: need M [e] + M*M [RVT] + M*M [RU] + BDSPAC
1856 CALL DBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
1857 $ M, RWORK( IRVT ), M, DUM, IDUM,
1858 $ RWORK( NRWORK ), IWORK, INFO )
1860 * Multiply Q in U by real matrix RWORK(IRVT)
1861 * storing the result in WORK(IVT), copying to U
1862 * CWorkspace: need 2*M [tauq, taup] + M*M [VT]
1863 * RWorkspace: need M [e] + M*M [RVT] + M*M [RU] + 2*M*M [rwork]
1865 CALL ZLACRM( M, M, U, LDU, RWORK( IRU ), M, WORK( IVT ),
1866 $ LDWKVT, RWORK( NRWORK ) )
1867 CALL ZLACPY( 'F', M, M, WORK( IVT ), LDWKVT, U, LDU )
1869 * Multiply RWORK(IRVT) by P**H in A, storing the
1870 * result in WORK(IVT), copying to A
1871 * CWorkspace: need 2*M [tauq, taup] + M*M [VT]
1872 * CWorkspace: prefer 2*M [tauq, taup] + M*N [VT]
1873 * RWorkspace: need M [e] + M*M [RVT] + 2*M*M [rwork]
1874 * RWorkspace: prefer M [e] + M*M [RVT] + 2*M*N [rwork] < M + 5*M*M since N < 2*M here
1877 DO 50 I = 1, N, CHUNK
1878 BLK = MIN( N-I+1, CHUNK )
1879 CALL ZLARCM( M, BLK, RWORK( IRVT ), M, A( 1, I ), LDA,
1880 $ WORK( IVT ), LDWKVT, RWORK( NRWORK ) )
1881 CALL ZLACPY( 'F', M, BLK, WORK( IVT ), LDWKVT,
1884 ELSE IF( WNTQS ) THEN
1886 * Path 5ts (N >> M, JOBZ='S')
1887 * Copy A to U, generate Q
1888 * CWorkspace: need 2*M [tauq, taup] + M [work]
1889 * CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
1890 * RWorkspace: need 0
1892 CALL ZLACPY( 'L', M, M, A, LDA, U, LDU )
1893 CALL ZUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
1894 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1896 * Copy A to VT, generate P**H
1897 * CWorkspace: need 2*M [tauq, taup] + M [work]
1898 * CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
1899 * RWorkspace: need 0
1901 CALL ZLACPY( 'U', M, N, A, LDA, VT, LDVT )
1902 CALL ZUNGBR( 'P', M, N, M, VT, LDVT, WORK( ITAUP ),
1903 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1905 * Perform bidiagonal SVD, computing left singular vectors
1906 * of bidiagonal matrix in RWORK(IRU) and computing right
1907 * singular vectors of bidiagonal matrix in RWORK(IRVT)
1908 * CWorkspace: need 0
1909 * RWorkspace: need M [e] + M*M [RVT] + M*M [RU] + BDSPAC
1914 CALL DBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
1915 $ M, RWORK( IRVT ), M, DUM, IDUM,
1916 $ RWORK( NRWORK ), IWORK, INFO )
1918 * Multiply Q in U by real matrix RWORK(IRU), storing the
1919 * result in A, copying to U
1920 * CWorkspace: need 0
1921 * RWorkspace: need M [e] + M*M [RVT] + M*M [RU] + 2*M*M [rwork]
1923 CALL ZLACRM( M, M, U, LDU, RWORK( IRU ), M, A, LDA,
1925 CALL ZLACPY( 'F', M, M, A, LDA, U, LDU )
1927 * Multiply real matrix RWORK(IRVT) by P**H in VT,
1928 * storing the result in A, copying to VT
1929 * CWorkspace: need 0
1930 * RWorkspace: need M [e] + M*M [RVT] + 2*M*N [rwork] < M + 5*M*M since N < 2*M here
1933 CALL ZLARCM( M, N, RWORK( IRVT ), M, VT, LDVT, A, LDA,
1935 CALL ZLACPY( 'F', M, N, A, LDA, VT, LDVT )
1938 * Path 5ta (N >> M, JOBZ='A')
1939 * Copy A to U, generate Q
1940 * CWorkspace: need 2*M [tauq, taup] + M [work]
1941 * CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
1942 * RWorkspace: need 0
1944 CALL ZLACPY( 'L', M, M, A, LDA, U, LDU )
1945 CALL ZUNGBR( 'Q', M, M, N, U, LDU, WORK( ITAUQ ),
1946 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1948 * Copy A to VT, generate P**H
1949 * CWorkspace: need 2*M [tauq, taup] + N [work]
1950 * CWorkspace: prefer 2*M [tauq, taup] + N*NB [work]
1951 * RWorkspace: need 0
1953 CALL ZLACPY( 'U', M, N, A, LDA, VT, LDVT )
1954 CALL ZUNGBR( 'P', N, N, M, VT, LDVT, WORK( ITAUP ),
1955 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
1957 * Perform bidiagonal SVD, computing left singular vectors
1958 * of bidiagonal matrix in RWORK(IRU) and computing right
1959 * singular vectors of bidiagonal matrix in RWORK(IRVT)
1960 * CWorkspace: need 0
1961 * RWorkspace: need M [e] + M*M [RVT] + M*M [RU] + BDSPAC
1966 CALL DBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
1967 $ M, RWORK( IRVT ), M, DUM, IDUM,
1968 $ RWORK( NRWORK ), IWORK, INFO )
1970 * Multiply Q in U by real matrix RWORK(IRU), storing the
1971 * result in A, copying to U
1972 * CWorkspace: need 0
1973 * RWorkspace: need M [e] + M*M [RVT] + M*M [RU] + 2*M*M [rwork]
1975 CALL ZLACRM( M, M, U, LDU, RWORK( IRU ), M, A, LDA,
1977 CALL ZLACPY( 'F', M, M, A, LDA, U, LDU )
1979 * Multiply real matrix RWORK(IRVT) by P**H in VT,
1980 * storing the result in A, copying to VT
1981 * CWorkspace: need 0
1982 * RWorkspace: need M [e] + M*M [RVT] + 2*M*N [rwork] < M + 5*M*M since N < 2*M here
1985 CALL ZLARCM( M, N, RWORK( IRVT ), M, VT, LDVT, A, LDA,
1987 CALL ZLACPY( 'F', M, N, A, LDA, VT, LDVT )
1994 * Path 6t (N > M, but not much larger)
1995 * Reduce to bidiagonal form without LQ decomposition
1996 * Use ZUNMBR to compute singular vectors
2005 * CWorkspace: need 2*M [tauq, taup] + N [work]
2006 * CWorkspace: prefer 2*M [tauq, taup] + (M+N)*NB [work]
2007 * RWorkspace: need M [e]
2009 CALL ZGEBRD( M, N, A, LDA, S, RWORK( IE ), WORK( ITAUQ ),
2010 $ WORK( ITAUP ), WORK( NWORK ), LWORK-NWORK+1,
2014 * Path 6tn (N > M, JOBZ='N')
2015 * Compute singular values only
2016 * CWorkspace: need 0
2017 * RWorkspace: need M [e] + BDSPAC
2019 CALL DBDSDC( 'L', 'N', M, S, RWORK( IE ), DUM,1,DUM,1,
2020 $ DUM, IDUM, RWORK( NRWORK ), IWORK, INFO )
2021 ELSE IF( WNTQO ) THEN
2022 * Path 6to (N > M, JOBZ='O')
2025 IF( LWORK .GE. M*N + 3*M ) THEN
2027 * WORK( IVT ) is M by N
2029 CALL ZLASET( 'F', M, N, CZERO, CZERO, WORK( IVT ),
2031 NWORK = IVT + LDWKVT*N
2034 * WORK( IVT ) is M by CHUNK
2036 CHUNK = ( LWORK - 3*M ) / M
2037 NWORK = IVT + LDWKVT*CHUNK
2040 * Perform bidiagonal SVD, computing left singular vectors
2041 * of bidiagonal matrix in RWORK(IRU) and computing right
2042 * singular vectors of bidiagonal matrix in RWORK(IRVT)
2043 * CWorkspace: need 0
2044 * RWorkspace: need M [e] + M*M [RVT] + M*M [RU] + BDSPAC
2049 CALL DBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
2050 $ M, RWORK( IRVT ), M, DUM, IDUM,
2051 $ RWORK( NRWORK ), IWORK, INFO )
2053 * Copy real matrix RWORK(IRU) to complex matrix U
2054 * Overwrite U by left singular vectors of A
2055 * CWorkspace: need 2*M [tauq, taup] + M*M [VT] + M [work]
2056 * CWorkspace: prefer 2*M [tauq, taup] + M*M [VT] + M*NB [work]
2057 * RWorkspace: need M [e] + M*M [RVT] + M*M [RU]
2059 CALL ZLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
2060 CALL ZUNMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
2061 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
2062 $ LWORK-NWORK+1, IERR )
2064 IF( LWORK .GE. M*N + 3*M ) THEN
2067 * Copy real matrix RWORK(IRVT) to complex matrix WORK(IVT)
2068 * Overwrite WORK(IVT) by right singular vectors of A,
2070 * CWorkspace: need 2*M [tauq, taup] + M*N [VT] + M [work]
2071 * CWorkspace: prefer 2*M [tauq, taup] + M*N [VT] + M*NB [work]
2072 * RWorkspace: need M [e] + M*M [RVT]
2074 CALL ZLACP2( 'F', M, M, RWORK( IRVT ), M, WORK( IVT ),
2076 CALL ZUNMBR( 'P', 'R', 'C', M, N, M, A, LDA,
2077 $ WORK( ITAUP ), WORK( IVT ), LDWKVT,
2078 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
2079 CALL ZLACPY( 'F', M, N, WORK( IVT ), LDWKVT, A, LDA )
2083 * Generate P**H in A
2084 * CWorkspace: need 2*M [tauq, taup] + M*M [VT] + M [work]
2085 * CWorkspace: prefer 2*M [tauq, taup] + M*M [VT] + M*NB [work]
2086 * RWorkspace: need 0
2088 CALL ZUNGBR( 'P', M, N, M, A, LDA, WORK( ITAUP ),
2089 $ WORK( NWORK ), LWORK-NWORK+1, IERR )
2091 * Multiply Q in A by real matrix RWORK(IRU), storing the
2092 * result in WORK(IU), copying to A
2093 * CWorkspace: need 2*M [tauq, taup] + M*M [VT]
2094 * CWorkspace: prefer 2*M [tauq, taup] + M*N [VT]
2095 * RWorkspace: need M [e] + M*M [RVT] + 2*M*M [rwork]
2096 * RWorkspace: prefer M [e] + M*M [RVT] + 2*M*N [rwork] < M + 5*M*M since N < 2*M here
2099 DO 60 I = 1, N, CHUNK
2100 BLK = MIN( N-I+1, CHUNK )
2101 CALL ZLARCM( M, BLK, RWORK( IRVT ), M, A( 1, I ),
2102 $ LDA, WORK( IVT ), LDWKVT,
2104 CALL ZLACPY( 'F', M, BLK, WORK( IVT ), LDWKVT,
2108 ELSE IF( WNTQS ) THEN
2110 * Path 6ts (N > M, JOBZ='S')
2111 * Perform bidiagonal SVD, computing left singular vectors
2112 * of bidiagonal matrix in RWORK(IRU) and computing right
2113 * singular vectors of bidiagonal matrix in RWORK(IRVT)
2114 * CWorkspace: need 0
2115 * RWorkspace: need M [e] + M*M [RVT] + M*M [RU] + BDSPAC
2120 CALL DBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
2121 $ M, RWORK( IRVT ), M, DUM, IDUM,
2122 $ RWORK( NRWORK ), IWORK, INFO )
2124 * Copy real matrix RWORK(IRU) to complex matrix U
2125 * Overwrite U by left singular vectors of A
2126 * CWorkspace: need 2*M [tauq, taup] + M [work]
2127 * CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
2128 * RWorkspace: need M [e] + M*M [RVT] + M*M [RU]
2130 CALL ZLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
2131 CALL ZUNMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
2132 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
2133 $ LWORK-NWORK+1, IERR )
2135 * Copy real matrix RWORK(IRVT) to complex matrix VT
2136 * Overwrite VT by right singular vectors of A
2137 * CWorkspace: need 2*M [tauq, taup] + M [work]
2138 * CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
2139 * RWorkspace: need M [e] + M*M [RVT]
2141 CALL ZLASET( 'F', M, N, CZERO, CZERO, VT, LDVT )
2142 CALL ZLACP2( 'F', M, M, RWORK( IRVT ), M, VT, LDVT )
2143 CALL ZUNMBR( 'P', 'R', 'C', M, N, M, A, LDA,
2144 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
2145 $ LWORK-NWORK+1, IERR )
2148 * Path 6ta (N > M, JOBZ='A')
2149 * Perform bidiagonal SVD, computing left singular vectors
2150 * of bidiagonal matrix in RWORK(IRU) and computing right
2151 * singular vectors of bidiagonal matrix in RWORK(IRVT)
2152 * CWorkspace: need 0
2153 * RWorkspace: need M [e] + M*M [RVT] + M*M [RU] + BDSPAC
2159 CALL DBDSDC( 'L', 'I', M, S, RWORK( IE ), RWORK( IRU ),
2160 $ M, RWORK( IRVT ), M, DUM, IDUM,
2161 $ RWORK( NRWORK ), IWORK, INFO )
2163 * Copy real matrix RWORK(IRU) to complex matrix U
2164 * Overwrite U by left singular vectors of A
2165 * CWorkspace: need 2*M [tauq, taup] + M [work]
2166 * CWorkspace: prefer 2*M [tauq, taup] + M*NB [work]
2167 * RWorkspace: need M [e] + M*M [RVT] + M*M [RU]
2169 CALL ZLACP2( 'F', M, M, RWORK( IRU ), M, U, LDU )
2170 CALL ZUNMBR( 'Q', 'L', 'N', M, M, N, A, LDA,
2171 $ WORK( ITAUQ ), U, LDU, WORK( NWORK ),
2172 $ LWORK-NWORK+1, IERR )
2174 * Set all of VT to identity matrix
2176 CALL ZLASET( 'F', N, N, CZERO, CONE, VT, LDVT )
2178 * Copy real matrix RWORK(IRVT) to complex matrix VT
2179 * Overwrite VT by right singular vectors of A
2180 * CWorkspace: need 2*M [tauq, taup] + N [work]
2181 * CWorkspace: prefer 2*M [tauq, taup] + N*NB [work]
2182 * RWorkspace: need M [e] + M*M [RVT]
2184 CALL ZLACP2( 'F', M, M, RWORK( IRVT ), M, VT, LDVT )
2185 CALL ZUNMBR( 'P', 'R', 'C', N, N, M, A, LDA,
2186 $ WORK( ITAUP ), VT, LDVT, WORK( NWORK ),
2187 $ LWORK-NWORK+1, IERR )
2194 * Undo scaling if necessary
2196 IF( ISCL.EQ.1 ) THEN
2197 IF( ANRM.GT.BIGNUM )
2198 $ CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1, S, MINMN,
2200 IF( INFO.NE.0 .AND. ANRM.GT.BIGNUM )
2201 $ CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN-1, 1,
2202 $ RWORK( IE ), MINMN, IERR )
2203 IF( ANRM.LT.SMLNUM )
2204 $ CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1, S, MINMN,
2206 IF( INFO.NE.0 .AND. ANRM.LT.SMLNUM )
2207 $ CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN-1, 1,
2208 $ RWORK( IE ), MINMN, IERR )
2211 * Return optimal workspace in WORK(1)