1 *> \brief <b> ZGESVDX computes the singular value decomposition (SVD) for GE matrices</b>
3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download ZGESVDX + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zgesvdx.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zgesvdx.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zgesvdx.f">
21 * SUBROUTINE CGESVDX( JOBU, JOBVT, RANGE, M, N, A, LDA, VL, VU,
22 * $ IL, IU, NS, S, U, LDU, VT, LDVT, WORK,
23 * $ LWORK, RWORK, IWORK, INFO )
26 * .. Scalar Arguments ..
27 * CHARACTER JOBU, JOBVT, RANGE
28 * INTEGER IL, INFO, IU, LDA, LDU, LDVT, LWORK, M, N, NS
29 * DOUBLE PRECISION VL, VU
31 * .. Array Arguments ..
33 * DOUBLE PRECISION S( * ), RWORK( * )
34 * COMPLEX*16 A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
44 *> ZGESVDX computes the singular value decomposition (SVD) of a complex
45 *> M-by-N matrix A, optionally computing the left and/or right singular
46 *> vectors. The SVD is written
48 *> A = U * SIGMA * transpose(V)
50 *> where SIGMA is an M-by-N matrix which is zero except for its
51 *> min(m,n) diagonal elements, U is an M-by-M unitary matrix, and
52 *> V is an N-by-N unitary matrix. The diagonal elements of SIGMA
53 *> are the singular values of A; they are real and non-negative, and
54 *> are returned in descending order. The first min(m,n) columns of
55 *> U and V are the left and right singular vectors of A.
57 *> ZGESVDX uses an eigenvalue problem for obtaining the SVD, which
58 *> allows for the computation of a subset of singular values and
59 *> vectors. See DBDSVDX for details.
61 *> Note that the routine returns V**T, not V.
69 *> JOBU is CHARACTER*1
70 *> Specifies options for computing all or part of the matrix U:
71 *> = 'V': the first min(m,n) columns of U (the left singular
72 *> vectors) or as specified by RANGE are returned in
74 *> = 'N': no columns of U (no left singular vectors) are
80 *> JOBVT is CHARACTER*1
81 *> Specifies options for computing all or part of the matrix
83 *> = 'V': the first min(m,n) rows of V**T (the right singular
84 *> vectors) or as specified by RANGE are returned in
86 *> = 'N': no rows of V**T (no right singular vectors) are
92 *> RANGE is CHARACTER*1
93 *> = 'A': all singular values will be found.
94 *> = 'V': all singular values in the half-open interval (VL,VU]
96 *> = 'I': the IL-th through IU-th singular values will be found.
102 *> The number of rows of the input matrix A. M >= 0.
108 *> The number of columns of the input matrix A. N >= 0.
113 *> A is COMPLEX*16 array, dimension (LDA,N)
114 *> On entry, the M-by-N matrix A.
115 *> On exit, the contents of A are destroyed.
121 *> The leading dimension of the array A. LDA >= max(1,M).
126 *> VL is DOUBLE PRECISION
127 *> If RANGE='V', the lower bound of the interval to
128 *> be searched for singular values. VU > VL.
129 *> Not referenced if RANGE = 'A' or 'I'.
134 *> VU is DOUBLE PRECISION
135 *> If RANGE='V', the upper bound of the interval to
136 *> be searched for singular values. VU > VL.
137 *> Not referenced if RANGE = 'A' or 'I'.
143 *> If RANGE='I', the index of the
144 *> smallest singular value to be returned.
145 *> 1 <= IL <= IU <= min(M,N), if min(M,N) > 0.
146 *> Not referenced if RANGE = 'A' or 'V'.
152 *> If RANGE='I', the index of the
153 *> largest singular value to be returned.
154 *> 1 <= IL <= IU <= min(M,N), if min(M,N) > 0.
155 *> Not referenced if RANGE = 'A' or 'V'.
161 *> The total number of singular values found,
162 *> 0 <= NS <= min(M,N).
163 *> If RANGE = 'A', NS = min(M,N); if RANGE = 'I', NS = IU-IL+1.
168 *> S is DOUBLE PRECISION array, dimension (min(M,N))
169 *> The singular values of A, sorted so that S(i) >= S(i+1).
174 *> U is COMPLEX*16 array, dimension (LDU,UCOL)
175 *> If JOBU = 'V', U contains columns of U (the left singular
176 *> vectors, stored columnwise) as specified by RANGE; if
177 *> JOBU = 'N', U is not referenced.
178 *> Note: The user must ensure that UCOL >= NS; if RANGE = 'V',
179 *> the exact value of NS is not known in advance and an upper
180 *> bound must be used.
186 *> The leading dimension of the array U. LDU >= 1; if
187 *> JOBU = 'V', LDU >= M.
192 *> VT is COMPLEX*16 array, dimension (LDVT,N)
193 *> If JOBVT = 'V', VT contains the rows of V**T (the right singular
194 *> vectors, stored rowwise) as specified by RANGE; if JOBVT = 'N',
195 *> VT is not referenced.
196 *> Note: The user must ensure that LDVT >= NS; if RANGE = 'V',
197 *> the exact value of NS is not known in advance and an upper
198 *> bound must be used.
204 *> The leading dimension of the array VT. LDVT >= 1; if
205 *> JOBVT = 'V', LDVT >= NS (see above).
210 *> WORK is COMPLEX*16 array, dimension (MAX(1,LWORK))
211 *> On exit, if INFO = 0, WORK(1) returns the optimal LWORK;
217 *> The dimension of the array WORK.
218 *> LWORK >= MAX(1,MIN(M,N)*(MIN(M,N)+4)) for the paths (see
219 *> comments inside the code):
220 *> - PATH 1 (M much larger than N)
221 *> - PATH 1t (N much larger than M)
222 *> LWORK >= MAX(1,MIN(M,N)*2+MAX(M,N)) for the other paths.
223 *> For good performance, LWORK should generally be larger.
225 *> If LWORK = -1, then a workspace query is assumed; the routine
226 *> only calculates the optimal size of the WORK array, returns
227 *> this value as the first entry of the WORK array, and no error
228 *> message related to LWORK is issued by XERBLA.
233 *> RWORK is DOUBLE PRECISION array, dimension (MAX(1,LRWORK))
234 *> LRWORK >= MIN(M,N)*(MIN(M,N)*2+15*MIN(M,N)).
239 *> IWORK is INTEGER array, dimension (12*MIN(M,N))
240 *> If INFO = 0, the first NS elements of IWORK are zero. If INFO > 0,
241 *> then IWORK contains the indices of the eigenvectors that failed
242 *> to converge in DBDSVDX/DSTEVX.
248 *> = 0: successful exit
249 *> < 0: if INFO = -i, the i-th argument had an illegal value
250 *> > 0: if INFO = i, then i eigenvectors failed to converge
251 *> in DBDSVDX/DSTEVX.
252 *> if INFO = N*2 + 1, an internal error occurred in
259 *> \author Univ. of Tennessee
260 *> \author Univ. of California Berkeley
261 *> \author Univ. of Colorado Denver
266 *> \ingroup complex16GEsing
268 * =====================================================================
269 SUBROUTINE ZGESVDX( JOBU, JOBVT, RANGE, M, N, A, LDA, VL, VU,
270 $ IL, IU, NS, S, U, LDU, VT, LDVT, WORK,
271 $ LWORK, RWORK, IWORK, INFO )
273 * -- LAPACK driver routine (version 3.6.1) --
274 * -- LAPACK is a software package provided by Univ. of Tennessee, --
275 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
278 * .. Scalar Arguments ..
279 CHARACTER JOBU, JOBVT, RANGE
280 INTEGER IL, INFO, IU, LDA, LDU, LDVT, LWORK, M, N, NS
281 DOUBLE PRECISION VL, VU
283 * .. Array Arguments ..
285 DOUBLE PRECISION S( * ), RWORK( * )
286 COMPLEX*16 A( LDA, * ), U( LDU, * ), VT( LDVT, * ),
290 * =====================================================================
293 COMPLEX*16 CZERO, CONE
294 PARAMETER ( CZERO = ( 0.0D0, 0.0D0 ),
295 $ CONE = ( 1.0D0, 0.0D0 ) )
296 DOUBLE PRECISION ZERO, ONE
297 PARAMETER ( ZERO = 0.0D0, ONE = 1.0D0 )
299 * .. Local Scalars ..
300 CHARACTER JOBZ, RNGTGK
301 LOGICAL ALLS, INDS, LQUERY, VALS, WANTU, WANTVT
302 INTEGER I, ID, IE, IERR, ILQF, ILTGK, IQRF, ISCL,
303 $ ITAU, ITAUP, ITAUQ, ITEMP, ITEMPR, ITGKZ,
304 $ IUTGK, J, K, MAXWRK, MINMN, MINWRK, MNTHR
305 DOUBLE PRECISION ABSTOL, ANRM, BIGNUM, EPS, SMLNUM
308 DOUBLE PRECISION DUM( 1 )
310 * .. External Subroutines ..
311 EXTERNAL ZGEBRD, ZGELQF, ZGEQRF, ZLASCL, ZLASET,
314 * .. External Functions ..
317 DOUBLE PRECISION DLAMCH, ZLANGE
318 EXTERNAL LSAME, ILAENV, DLAMCH, ZLANGE
320 * .. Intrinsic Functions ..
321 INTRINSIC MAX, MIN, SQRT
323 * .. Executable Statements ..
325 * Test the input arguments.
329 ABSTOL = 2*DLAMCH('S')
330 LQUERY = ( LWORK.EQ.-1 )
333 WANTU = LSAME( JOBU, 'V' )
334 WANTVT = LSAME( JOBVT, 'V' )
335 IF( WANTU .OR. WANTVT ) THEN
340 ALLS = LSAME( RANGE, 'A' )
341 VALS = LSAME( RANGE, 'V' )
342 INDS = LSAME( RANGE, 'I' )
345 IF( .NOT.LSAME( JOBU, 'V' ) .AND.
346 $ .NOT.LSAME( JOBU, 'N' ) ) THEN
348 ELSE IF( .NOT.LSAME( JOBVT, 'V' ) .AND.
349 $ .NOT.LSAME( JOBVT, 'N' ) ) THEN
351 ELSE IF( .NOT.( ALLS .OR. VALS .OR. INDS ) ) THEN
353 ELSE IF( M.LT.0 ) THEN
355 ELSE IF( N.LT.0 ) THEN
357 ELSE IF( M.GT.LDA ) THEN
359 ELSE IF( MINMN.GT.0 ) THEN
361 IF( VL.LT.ZERO ) THEN
363 ELSE IF( VU.LE.VL ) THEN
367 IF( IL.LT.1 .OR. IL.GT.MAX( 1, MINMN ) ) THEN
369 ELSE IF( IU.LT.MIN( MINMN, IL ) .OR. IU.GT.MINMN ) THEN
374 IF( WANTU .AND. LDU.LT.M ) THEN
376 ELSE IF( WANTVT ) THEN
378 IF( LDVT.LT.IU-IL+1 ) THEN
381 ELSE IF( LDVT.LT.MINMN ) THEN
389 * (Note: Comments in the code beginning "Workspace:" describe the
390 * minimal amount of workspace needed at that point in the code,
391 * as well as the preferred amount for good performance.
392 * NB refers to the optimal block size for the immediately
393 * following subroutine, as returned by ILAENV.)
398 IF( MINMN.GT.0 ) THEN
400 MNTHR = ILAENV( 6, 'ZGESVD', JOBU // JOBVT, M, N, 0, 0 )
401 IF( M.GE.MNTHR ) THEN
403 * Path 1 (M much larger than N)
406 MAXWRK = N + N*ILAENV(1,'ZGEQRF',' ',M,N,-1,-1)
408 $ N*N+2*N+2*N*ILAENV(1,'ZGEBRD',' ',N,N,-1,-1))
409 IF (WANTU .OR. WANTVT) THEN
411 $ N*N+2*N+N*ILAENV(1,'ZUNMQR','LN',N,N,N,-1))
415 * Path 2 (M at least N, but not much larger)
418 MAXWRK = 2*N + (M+N)*ILAENV(1,'ZGEBRD',' ',M,N,-1,-1)
419 IF (WANTU .OR. WANTVT) THEN
421 $ 2*N+N*ILAENV(1,'ZUNMQR','LN',N,N,N,-1))
425 MNTHR = ILAENV( 6, 'ZGESVD', JOBU // JOBVT, M, N, 0, 0 )
426 IF( N.GE.MNTHR ) THEN
428 * Path 1t (N much larger than M)
431 MAXWRK = M + M*ILAENV(1,'ZGELQF',' ',M,N,-1,-1)
433 $ M*M+2*M+2*M*ILAENV(1,'ZGEBRD',' ',M,M,-1,-1))
434 IF (WANTU .OR. WANTVT) THEN
436 $ M*M+2*M+M*ILAENV(1,'ZUNMQR','LN',M,M,M,-1))
440 * Path 2t (N greater than M, but not much larger)
444 MAXWRK = 2*M + (M+N)*ILAENV(1,'ZGEBRD',' ',M,N,-1,-1)
445 IF (WANTU .OR. WANTVT) THEN
447 $ 2*M+M*ILAENV(1,'ZUNMQR','LN',M,M,M,-1))
452 MAXWRK = MAX( MAXWRK, MINWRK )
453 WORK( 1 ) = DCMPLX( DBLE( MAXWRK ), ZERO )
455 IF( LWORK.LT.MINWRK .AND. .NOT.LQUERY ) THEN
461 CALL XERBLA( 'ZGESVDX', -INFO )
463 ELSE IF( LQUERY ) THEN
467 * Quick return if possible
469 IF( M.EQ.0 .OR. N.EQ.0 ) THEN
473 * Set singular values indices accord to RANGE='A'.
489 * Get machine constants
492 SMLNUM = SQRT( DLAMCH( 'S' ) ) / EPS
493 BIGNUM = ONE / SMLNUM
495 * Scale A if max element outside range [SMLNUM,BIGNUM]
497 ANRM = ZLANGE( 'M', M, N, A, LDA, DUM )
499 IF( ANRM.GT.ZERO .AND. ANRM.LT.SMLNUM ) THEN
501 CALL ZLASCL( 'G', 0, 0, ANRM, SMLNUM, M, N, A, LDA, INFO )
502 ELSE IF( ANRM.GT.BIGNUM ) THEN
504 CALL ZLASCL( 'G', 0, 0, ANRM, BIGNUM, M, N, A, LDA, INFO )
509 * A has at least as many rows as columns. If A has sufficiently
510 * more rows than columns, first reduce A using the QR
513 IF( M.GE.MNTHR ) THEN
515 * Path 1 (M much larger than N):
516 * A = Q * R = Q * ( QB * B * PB**T )
517 * = Q * ( QB * ( UB * S * VB**T ) * PB**T )
518 * U = Q * QB * UB; V**T = VB**T * PB**T
521 * (Workspace: need 2*N, prefer N+N*NB)
525 CALL ZGEQRF( M, N, A, LDA, WORK( ITAU ), WORK( ITEMP ),
526 $ LWORK-ITEMP+1, INFO )
528 * Copy R into WORK and bidiagonalize it:
529 * (Workspace: need N*N+3*N, prefer N*N+N+2*N*NB)
538 CALL ZLACPY( 'U', N, N, A, LDA, WORK( IQRF ), N )
539 CALL ZLASET( 'L', N-1, N-1, CZERO, CZERO,
540 $ WORK( IQRF+1 ), N )
541 CALL ZGEBRD( N, N, WORK( IQRF ), N, RWORK( ID ),
542 $ RWORK( IE ), WORK( ITAUQ ), WORK( ITAUP ),
543 $ WORK( ITEMP ), LWORK-ITEMP+1, INFO )
544 ITEMPR = ITGKZ + N*(N*2+1)
546 * Solve eigenvalue problem TGK*Z=Z*S.
547 * (Workspace: need 2*N*N+14*N)
549 CALL DBDSVDX( 'U', JOBZ, RNGTGK, N, RWORK( ID ),
550 $ RWORK( IE ), VL, VU, ILTGK, IUTGK, NS, S,
551 $ RWORK( ITGKZ ), N*2, RWORK( ITEMPR ),
554 * If needed, compute left singular vectors.
560 U( J, I ) = DCMPLX( RWORK( K ), ZERO )
565 CALL ZLASET( 'A', M-N, NS, CZERO, CZERO, U( N+1,1 ), LDU)
567 * Call ZUNMBR to compute QB*UB.
568 * (Workspace in WORK( ITEMP ): need N, prefer N*NB)
570 CALL ZUNMBR( 'Q', 'L', 'N', N, NS, N, WORK( IQRF ), N,
571 $ WORK( ITAUQ ), U, LDU, WORK( ITEMP ),
572 $ LWORK-ITEMP+1, INFO )
574 * Call ZUNMQR to compute Q*(QB*UB).
575 * (Workspace in WORK( ITEMP ): need N, prefer N*NB)
577 CALL ZUNMQR( 'L', 'N', M, NS, N, A, LDA,
578 $ WORK( ITAU ), U, LDU, WORK( ITEMP ),
579 $ LWORK-ITEMP+1, INFO )
582 * If needed, compute right singular vectors.
588 VT( I, J ) = DCMPLX( RWORK( K ), ZERO )
594 * Call ZUNMBR to compute VB**T * PB**T
595 * (Workspace in WORK( ITEMP ): need N, prefer N*NB)
597 CALL ZUNMBR( 'P', 'R', 'C', NS, N, N, WORK( IQRF ), N,
598 $ WORK( ITAUP ), VT, LDVT, WORK( ITEMP ),
599 $ LWORK-ITEMP+1, INFO )
603 * Path 2 (M at least N, but not much larger)
604 * Reduce A to bidiagonal form without QR decomposition
605 * A = QB * B * PB**T = QB * ( UB * S * VB**T ) * PB**T
606 * U = QB * UB; V**T = VB**T * PB**T
609 * (Workspace: need 2*N+M, prefer 2*N+(M+N)*NB)
617 CALL ZGEBRD( M, N, A, LDA, RWORK( ID ), RWORK( IE ),
618 $ WORK( ITAUQ ), WORK( ITAUP ), WORK( ITEMP ),
619 $ LWORK-ITEMP+1, INFO )
620 ITEMPR = ITGKZ + N*(N*2+1)
622 * Solve eigenvalue problem TGK*Z=Z*S.
623 * (Workspace: need 2*N*N+14*N)
625 CALL DBDSVDX( 'U', JOBZ, RNGTGK, N, RWORK( ID ),
626 $ RWORK( IE ), VL, VU, ILTGK, IUTGK, NS, S,
627 $ RWORK( ITGKZ ), N*2, RWORK( ITEMPR ),
630 * If needed, compute left singular vectors.
636 U( J, I ) = DCMPLX( RWORK( K ), ZERO )
641 CALL ZLASET( 'A', M-N, NS, CZERO, CZERO, U( N+1,1 ), LDU)
643 * Call ZUNMBR to compute QB*UB.
644 * (Workspace in WORK( ITEMP ): need N, prefer N*NB)
646 CALL ZUNMBR( 'Q', 'L', 'N', M, NS, N, A, LDA,
647 $ WORK( ITAUQ ), U, LDU, WORK( ITEMP ),
648 $ LWORK-ITEMP+1, IERR )
651 * If needed, compute right singular vectors.
657 VT( I, J ) = DCMPLX( RWORK( K ), ZERO )
663 * Call ZUNMBR to compute VB**T * PB**T
664 * (Workspace in WORK( ITEMP ): need N, prefer N*NB)
666 CALL ZUNMBR( 'P', 'R', 'C', NS, N, N, A, LDA,
667 $ WORK( ITAUP ), VT, LDVT, WORK( ITEMP ),
668 $ LWORK-ITEMP+1, IERR )
673 * A has more columns than rows. If A has sufficiently more
674 * columns than rows, first reduce A using the LQ decomposition.
676 IF( N.GE.MNTHR ) THEN
678 * Path 1t (N much larger than M):
679 * A = L * Q = ( QB * B * PB**T ) * Q
680 * = ( QB * ( UB * S * VB**T ) * PB**T ) * Q
681 * U = QB * UB ; V**T = VB**T * PB**T * Q
684 * (Workspace: need 2*M, prefer M+M*NB)
688 CALL ZGELQF( M, N, A, LDA, WORK( ITAU ), WORK( ITEMP ),
689 $ LWORK-ITEMP+1, INFO )
691 * Copy L into WORK and bidiagonalize it:
692 * (Workspace in WORK( ITEMP ): need M*M+3*M, prefer M*M+M+2*M*NB)
701 CALL ZLACPY( 'L', M, M, A, LDA, WORK( ILQF ), M )
702 CALL ZLASET( 'U', M-1, M-1, CZERO, CZERO,
703 $ WORK( ILQF+M ), M )
704 CALL ZGEBRD( M, M, WORK( ILQF ), M, RWORK( ID ),
705 $ RWORK( IE ), WORK( ITAUQ ), WORK( ITAUP ),
706 $ WORK( ITEMP ), LWORK-ITEMP+1, INFO )
707 ITEMPR = ITGKZ + M*(M*2+1)
709 * Solve eigenvalue problem TGK*Z=Z*S.
710 * (Workspace: need 2*M*M+14*M)
712 CALL DBDSVDX( 'U', JOBZ, RNGTGK, M, RWORK( ID ),
713 $ RWORK( IE ), VL, VU, ILTGK, IUTGK, NS, S,
714 $ RWORK( ITGKZ ), M*2, RWORK( ITEMPR ),
717 * If needed, compute left singular vectors.
723 U( J, I ) = DCMPLX( RWORK( K ), ZERO )
729 * Call ZUNMBR to compute QB*UB.
730 * (Workspace in WORK( ITEMP ): need M, prefer M*NB)
732 CALL ZUNMBR( 'Q', 'L', 'N', M, NS, M, WORK( ILQF ), M,
733 $ WORK( ITAUQ ), U, LDU, WORK( ITEMP ),
734 $ LWORK-ITEMP+1, INFO )
737 * If needed, compute right singular vectors.
743 VT( I, J ) = DCMPLX( RWORK( K ), ZERO )
748 CALL ZLASET( 'A', NS, N-M, CZERO, CZERO,
749 $ VT( 1,M+1 ), LDVT )
751 * Call ZUNMBR to compute (VB**T)*(PB**T)
752 * (Workspace in WORK( ITEMP ): need M, prefer M*NB)
754 CALL ZUNMBR( 'P', 'R', 'C', NS, M, M, WORK( ILQF ), M,
755 $ WORK( ITAUP ), VT, LDVT, WORK( ITEMP ),
756 $ LWORK-ITEMP+1, INFO )
758 * Call ZUNMLQ to compute ((VB**T)*(PB**T))*Q.
759 * (Workspace in WORK( ITEMP ): need M, prefer M*NB)
761 CALL ZUNMLQ( 'R', 'N', NS, N, M, A, LDA,
762 $ WORK( ITAU ), VT, LDVT, WORK( ITEMP ),
763 $ LWORK-ITEMP+1, INFO )
767 * Path 2t (N greater than M, but not much larger)
768 * Reduce to bidiagonal form without LQ decomposition
769 * A = QB * B * PB**T = QB * ( UB * S * VB**T ) * PB**T
770 * U = QB * UB; V**T = VB**T * PB**T
773 * (Workspace: need 2*M+N, prefer 2*M+(M+N)*NB)
781 CALL ZGEBRD( M, N, A, LDA, RWORK( ID ), RWORK( IE ),
782 $ WORK( ITAUQ ), WORK( ITAUP ), WORK( ITEMP ),
783 $ LWORK-ITEMP+1, INFO )
784 ITEMPR = ITGKZ + M*(M*2+1)
786 * Solve eigenvalue problem TGK*Z=Z*S.
787 * (Workspace: need 2*M*M+14*M)
789 CALL DBDSVDX( 'L', JOBZ, RNGTGK, M, RWORK( ID ),
790 $ RWORK( IE ), VL, VU, ILTGK, IUTGK, NS, S,
791 $ RWORK( ITGKZ ), M*2, RWORK( ITEMPR ),
794 * If needed, compute left singular vectors.
800 U( J, I ) = DCMPLX( RWORK( K ), ZERO )
806 * Call ZUNMBR to compute QB*UB.
807 * (Workspace in WORK( ITEMP ): need M, prefer M*NB)
809 CALL ZUNMBR( 'Q', 'L', 'N', M, NS, N, A, LDA,
810 $ WORK( ITAUQ ), U, LDU, WORK( ITEMP ),
811 $ LWORK-ITEMP+1, INFO )
814 * If needed, compute right singular vectors.
820 VT( I, J ) = DCMPLX( RWORK( K ), ZERO )
825 CALL ZLASET( 'A', NS, N-M, CZERO, CZERO,
826 $ VT( 1,M+1 ), LDVT )
828 * Call ZUNMBR to compute VB**T * PB**T
829 * (Workspace in WORK( ITEMP ): need M, prefer M*NB)
831 CALL ZUNMBR( 'P', 'R', 'C', NS, N, M, A, LDA,
832 $ WORK( ITAUP ), VT, LDVT, WORK( ITEMP ),
833 $ LWORK-ITEMP+1, INFO )
838 * Undo scaling if necessary
842 $ CALL DLASCL( 'G', 0, 0, BIGNUM, ANRM, MINMN, 1,
845 $ CALL DLASCL( 'G', 0, 0, SMLNUM, ANRM, MINMN, 1,
849 * Return optimal workspace in WORK(1)
851 WORK( 1 ) = DCMPLX( DBLE( MAXWRK ), ZERO )