LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
zgesvdq.f
Go to the documentation of this file.
1*> \brief <b> ZGESVDQ computes the singular value decomposition (SVD) with a QR-Preconditioned QR SVD Method for GE matrices</b>
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download ZGESVDQ + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zgesvdq.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zgesvdq.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zgesvdq.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE ZGESVDQ( JOBA, JOBP, JOBR, JOBU, JOBV, M, N, A, LDA,
20* S, U, LDU, V, LDV, NUMRANK, IWORK, LIWORK,
21* CWORK, LCWORK, RWORK, LRWORK, INFO )
22*
23* .. Scalar Arguments ..
24* IMPLICIT NONE
25* CHARACTER JOBA, JOBP, JOBR, JOBU, JOBV
26* INTEGER M, N, LDA, LDU, LDV, NUMRANK, LIWORK, LCWORK, LRWORK,
27* INFO
28* ..
29* .. Array Arguments ..
30* COMPLEX*16 A( LDA, * ), U( LDU, * ), V( LDV, * ), CWORK( * )
31* DOUBLE PRECISION S( * ), RWORK( * )
32* INTEGER IWORK( * )
33* ..
34*
35*
36*> \par Purpose:
37* =============
38*>
39*> \verbatim
40*>
41*> ZCGESVDQ computes the singular value decomposition (SVD) of a complex
42*> M-by-N matrix A, where M >= N. The SVD of A is written as
43*> [++] [xx] [x0] [xx]
44*> A = U * SIGMA * V^*, [++] = [xx] * [ox] * [xx]
45*> [++] [xx]
46*> where SIGMA is an N-by-N diagonal matrix, U is an M-by-N orthonormal
47*> matrix, and V is an N-by-N unitary matrix. The diagonal elements
48*> of SIGMA are the singular values of A. The columns of U and V are the
49*> left and the right singular vectors of A, respectively.
50*> \endverbatim
51*
52* Arguments:
53* ==========
54*
55*> \param[in] JOBA
56*> \verbatim
57*> JOBA is CHARACTER*1
58*> Specifies the level of accuracy in the computed SVD
59*> = 'A' The requested accuracy corresponds to having the backward
60*> error bounded by || delta A ||_F <= f(m,n) * EPS * || A ||_F,
61*> where EPS = DLAMCH('Epsilon'). This authorises ZGESVDQ to
62*> truncate the computed triangular factor in a rank revealing
63*> QR factorization whenever the truncated part is below the
64*> threshold of the order of EPS * ||A||_F. This is aggressive
65*> truncation level.
66*> = 'M' Similarly as with 'A', but the truncation is more gentle: it
67*> is allowed only when there is a drop on the diagonal of the
68*> triangular factor in the QR factorization. This is medium
69*> truncation level.
70*> = 'H' High accuracy requested. No numerical rank determination based
71*> on the rank revealing QR factorization is attempted.
72*> = 'E' Same as 'H', and in addition the condition number of column
73*> scaled A is estimated and returned in RWORK(1).
74*> N^(-1/4)*RWORK(1) <= ||pinv(A_scaled)||_2 <= N^(1/4)*RWORK(1)
75*> \endverbatim
76*>
77*> \param[in] JOBP
78*> \verbatim
79*> JOBP is CHARACTER*1
80*> = 'P' The rows of A are ordered in decreasing order with respect to
81*> ||A(i,:)||_\infty. This enhances numerical accuracy at the cost
82*> of extra data movement. Recommended for numerical robustness.
83*> = 'N' No row pivoting.
84*> \endverbatim
85*>
86*> \param[in] JOBR
87*> \verbatim
88*> JOBR is CHARACTER*1
89*> = 'T' After the initial pivoted QR factorization, ZGESVD is applied to
90*> the adjoint R**H of the computed triangular factor R. This involves
91*> some extra data movement (matrix transpositions). Useful for
92*> experiments, research and development.
93*> = 'N' The triangular factor R is given as input to CGESVD. This may be
94*> preferred as it involves less data movement.
95*> \endverbatim
96*>
97*> \param[in] JOBU
98*> \verbatim
99*> JOBU is CHARACTER*1
100*> = 'A' All M left singular vectors are computed and returned in the
101*> matrix U. See the description of U.
102*> = 'S' or 'U' N = min(M,N) left singular vectors are computed and returned
103*> in the matrix U. See the description of U.
104*> = 'R' Numerical rank NUMRANK is determined and only NUMRANK left singular
105*> vectors are computed and returned in the matrix U.
106*> = 'F' The N left singular vectors are returned in factored form as the
107*> product of the Q factor from the initial QR factorization and the
108*> N left singular vectors of (R**H , 0)**H. If row pivoting is used,
109*> then the necessary information on the row pivoting is stored in
110*> IWORK(N+1:N+M-1).
111*> = 'N' The left singular vectors are not computed.
112*> \endverbatim
113*>
114*> \param[in] JOBV
115*> \verbatim
116*> JOBV is CHARACTER*1
117*> = 'A', 'V' All N right singular vectors are computed and returned in
118*> the matrix V.
119*> = 'R' Numerical rank NUMRANK is determined and only NUMRANK right singular
120*> vectors are computed and returned in the matrix V. This option is
121*> allowed only if JOBU = 'R' or JOBU = 'N'; otherwise it is illegal.
122*> = 'N' The right singular vectors are not computed.
123*> \endverbatim
124*>
125*> \param[in] M
126*> \verbatim
127*> M is INTEGER
128*> The number of rows of the input matrix A. M >= 0.
129*> \endverbatim
130*>
131*> \param[in] N
132*> \verbatim
133*> N is INTEGER
134*> The number of columns of the input matrix A. M >= N >= 0.
135*> \endverbatim
136*>
137*> \param[in,out] A
138*> \verbatim
139*> A is COMPLEX*16 array of dimensions LDA x N
140*> On entry, the input matrix A.
141*> On exit, if JOBU .NE. 'N' or JOBV .NE. 'N', the lower triangle of A contains
142*> the Householder vectors as stored by ZGEQP3. If JOBU = 'F', these Householder
143*> vectors together with CWORK(1:N) can be used to restore the Q factors from
144*> the initial pivoted QR factorization of A. See the description of U.
145*> \endverbatim
146*>
147*> \param[in] LDA
148*> \verbatim
149*> LDA is INTEGER.
150*> The leading dimension of the array A. LDA >= max(1,M).
151*> \endverbatim
152*>
153*> \param[out] S
154*> \verbatim
155*> S is DOUBLE PRECISION array of dimension N.
156*> The singular values of A, ordered so that S(i) >= S(i+1).
157*> \endverbatim
158*>
159*> \param[out] U
160*> \verbatim
161*> U is COMPLEX*16 array, dimension
162*> LDU x M if JOBU = 'A'; see the description of LDU. In this case,
163*> on exit, U contains the M left singular vectors.
164*> LDU x N if JOBU = 'S', 'U', 'R' ; see the description of LDU. In this
165*> case, U contains the leading N or the leading NUMRANK left singular vectors.
166*> LDU x N if JOBU = 'F' ; see the description of LDU. In this case U
167*> contains N x N unitary matrix that can be used to form the left
168*> singular vectors.
169*> If JOBU = 'N', U is not referenced.
170*> \endverbatim
171*>
172*> \param[in] LDU
173*> \verbatim
174*> LDU is INTEGER.
175*> The leading dimension of the array U.
176*> If JOBU = 'A', 'S', 'U', 'R', LDU >= max(1,M).
177*> If JOBU = 'F', LDU >= max(1,N).
178*> Otherwise, LDU >= 1.
179*> \endverbatim
180*>
181*> \param[out] V
182*> \verbatim
183*> V is COMPLEX*16 array, dimension
184*> LDV x N if JOBV = 'A', 'V', 'R' or if JOBA = 'E' .
185*> If JOBV = 'A', or 'V', V contains the N-by-N unitary matrix V**H;
186*> If JOBV = 'R', V contains the first NUMRANK rows of V**H (the right
187*> singular vectors, stored rowwise, of the NUMRANK largest singular values).
188*> If JOBV = 'N' and JOBA = 'E', V is used as a workspace.
189*> If JOBV = 'N', and JOBA.NE.'E', V is not referenced.
190*> \endverbatim
191*>
192*> \param[in] LDV
193*> \verbatim
194*> LDV is INTEGER
195*> The leading dimension of the array V.
196*> If JOBV = 'A', 'V', 'R', or JOBA = 'E', LDV >= max(1,N).
197*> Otherwise, LDV >= 1.
198*> \endverbatim
199*>
200*> \param[out] NUMRANK
201*> \verbatim
202*> NUMRANK is INTEGER
203*> NUMRANK is the numerical rank first determined after the rank
204*> revealing QR factorization, following the strategy specified by the
205*> value of JOBA. If JOBV = 'R' and JOBU = 'R', only NUMRANK
206*> leading singular values and vectors are then requested in the call
207*> of CGESVD. The final value of NUMRANK might be further reduced if
208*> some singular values are computed as zeros.
209*> \endverbatim
210*>
211*> \param[out] IWORK
212*> \verbatim
213*> IWORK is INTEGER array, dimension (max(1, LIWORK)).
214*> On exit, IWORK(1:N) contains column pivoting permutation of the
215*> rank revealing QR factorization.
216*> If JOBP = 'P', IWORK(N+1:N+M-1) contains the indices of the sequence
217*> of row swaps used in row pivoting. These can be used to restore the
218*> left singular vectors in the case JOBU = 'F'.
219*>
220*> If LIWORK, LCWORK, or LRWORK = -1, then on exit, if INFO = 0,
221*> IWORK(1) returns the minimal LIWORK.
222*> \endverbatim
223*>
224*> \param[in] LIWORK
225*> \verbatim
226*> LIWORK is INTEGER
227*> The dimension of the array IWORK.
228*> LIWORK >= N + M - 1, if JOBP = 'P';
229*> LIWORK >= N if JOBP = 'N'.
230*>
231*> If LIWORK = -1, then a workspace query is assumed; the routine
232*> only calculates and returns the optimal and minimal sizes
233*> for the CWORK, IWORK, and RWORK arrays, and no error
234*> message related to LCWORK is issued by XERBLA.
235*> \endverbatim
236*>
237*> \param[out] CWORK
238*> \verbatim
239*> CWORK is COMPLEX*12 array, dimension (max(2, LCWORK)), used as a workspace.
240*> On exit, if, on entry, LCWORK.NE.-1, CWORK(1:N) contains parameters
241*> needed to recover the Q factor from the QR factorization computed by
242*> ZGEQP3.
243*>
244*> If LIWORK, LCWORK, or LRWORK = -1, then on exit, if INFO = 0,
245*> CWORK(1) returns the optimal LCWORK, and
246*> CWORK(2) returns the minimal LCWORK.
247*> \endverbatim
248*>
249*> \param[in,out] LCWORK
250*> \verbatim
251*> LCWORK is INTEGER
252*> The dimension of the array CWORK. It is determined as follows:
253*> Let LWQP3 = N+1, LWCON = 2*N, and let
254*> LWUNQ = { MAX( N, 1 ), if JOBU = 'R', 'S', or 'U'
255*> { MAX( M, 1 ), if JOBU = 'A'
256*> LWSVD = MAX( 3*N, 1 )
257*> LWLQF = MAX( N/2, 1 ), LWSVD2 = MAX( 3*(N/2), 1 ), LWUNLQ = MAX( N, 1 ),
258*> LWQRF = MAX( N/2, 1 ), LWUNQ2 = MAX( N, 1 )
259*> Then the minimal value of LCWORK is:
260*> = MAX( N + LWQP3, LWSVD ) if only the singular values are needed;
261*> = MAX( N + LWQP3, LWCON, LWSVD ) if only the singular values are needed,
262*> and a scaled condition estimate requested;
263*>
264*> = N + MAX( LWQP3, LWSVD, LWUNQ ) if the singular values and the left
265*> singular vectors are requested;
266*> = N + MAX( LWQP3, LWCON, LWSVD, LWUNQ ) if the singular values and the left
267*> singular vectors are requested, and also
268*> a scaled condition estimate requested;
269*>
270*> = N + MAX( LWQP3, LWSVD ) if the singular values and the right
271*> singular vectors are requested;
272*> = N + MAX( LWQP3, LWCON, LWSVD ) if the singular values and the right
273*> singular vectors are requested, and also
274*> a scaled condition etimate requested;
275*>
276*> = N + MAX( LWQP3, LWSVD, LWUNQ ) if the full SVD is requested with JOBV = 'R';
277*> independent of JOBR;
278*> = N + MAX( LWQP3, LWCON, LWSVD, LWUNQ ) if the full SVD is requested,
279*> JOBV = 'R' and, also a scaled condition
280*> estimate requested; independent of JOBR;
281*> = MAX( N + MAX( LWQP3, LWSVD, LWUNQ ),
282*> N + MAX( LWQP3, N/2+LWLQF, N/2+LWSVD2, N/2+LWUNLQ, LWUNQ) ) if the
283*> full SVD is requested with JOBV = 'A' or 'V', and
284*> JOBR ='N'
285*> = MAX( N + MAX( LWQP3, LWCON, LWSVD, LWUNQ ),
286*> N + MAX( LWQP3, LWCON, N/2+LWLQF, N/2+LWSVD2, N/2+LWUNLQ, LWUNQ ) )
287*> if the full SVD is requested with JOBV = 'A' or 'V', and
288*> JOBR ='N', and also a scaled condition number estimate
289*> requested.
290*> = MAX( N + MAX( LWQP3, LWSVD, LWUNQ ),
291*> N + MAX( LWQP3, N/2+LWQRF, N/2+LWSVD2, N/2+LWUNQ2, LWUNQ ) ) if the
292*> full SVD is requested with JOBV = 'A', 'V', and JOBR ='T'
293*> = MAX( N + MAX( LWQP3, LWCON, LWSVD, LWUNQ ),
294*> N + MAX( LWQP3, LWCON, N/2+LWQRF, N/2+LWSVD2, N/2+LWUNQ2, LWUNQ ) )
295*> if the full SVD is requested with JOBV = 'A', 'V' and
296*> JOBR ='T', and also a scaled condition number estimate
297*> requested.
298*> Finally, LCWORK must be at least two: LCWORK = MAX( 2, LCWORK ).
299*>
300*> If LCWORK = -1, then a workspace query is assumed; the routine
301*> only calculates and returns the optimal and minimal sizes
302*> for the CWORK, IWORK, and RWORK arrays, and no error
303*> message related to LCWORK is issued by XERBLA.
304*> \endverbatim
305*>
306*> \param[out] RWORK
307*> \verbatim
308*> RWORK is DOUBLE PRECISION array, dimension (max(1, LRWORK)).
309*> On exit,
310*> 1. If JOBA = 'E', RWORK(1) contains an estimate of the condition
311*> number of column scaled A. If A = C * D where D is diagonal and C
312*> has unit columns in the Euclidean norm, then, assuming full column rank,
313*> N^(-1/4) * RWORK(1) <= ||pinv(C)||_2 <= N^(1/4) * RWORK(1).
314*> Otherwise, RWORK(1) = -1.
315*> 2. RWORK(2) contains the number of singular values computed as
316*> exact zeros in ZGESVD applied to the upper triangular or trapezoidal
317*> R (from the initial QR factorization). In case of early exit (no call to
318*> ZGESVD, such as in the case of zero matrix) RWORK(2) = -1.
319*>
320*> If LIWORK, LCWORK, or LRWORK = -1, then on exit, if INFO = 0,
321*> RWORK(1) returns the minimal LRWORK.
322*> \endverbatim
323*>
324*> \param[in] LRWORK
325*> \verbatim
326*> LRWORK is INTEGER.
327*> The dimension of the array RWORK.
328*> If JOBP ='P', then LRWORK >= MAX(2, M, 5*N);
329*> Otherwise, LRWORK >= MAX(2, 5*N).
330*>
331*> If LRWORK = -1, then a workspace query is assumed; the routine
332*> only calculates and returns the optimal and minimal sizes
333*> for the CWORK, IWORK, and RWORK arrays, and no error
334*> message related to LCWORK is issued by XERBLA.
335*> \endverbatim
336*>
337*> \param[out] INFO
338*> \verbatim
339*> INFO is INTEGER
340*> = 0: successful exit.
341*> < 0: if INFO = -i, the i-th argument had an illegal value.
342*> > 0: if ZBDSQR did not converge, INFO specifies how many superdiagonals
343*> of an intermediate bidiagonal form B (computed in ZGESVD) did not
344*> converge to zero.
345*> \endverbatim
346*
347*> \par Further Details:
348* ========================
349*>
350*> \verbatim
351*>
352*> 1. The data movement (matrix transpose) is coded using simple nested
353*> DO-loops because BLAS and LAPACK do not provide corresponding subroutines.
354*> Those DO-loops are easily identified in this source code - by the CONTINUE
355*> statements labeled with 11**. In an optimized version of this code, the
356*> nested DO loops should be replaced with calls to an optimized subroutine.
357*> 2. This code scales A by 1/SQRT(M) if the largest ABS(A(i,j)) could cause
358*> column norm overflow. This is the minial precaution and it is left to the
359*> SVD routine (CGESVD) to do its own preemptive scaling if potential over-
360*> or underflows are detected. To avoid repeated scanning of the array A,
361*> an optimal implementation would do all necessary scaling before calling
362*> CGESVD and the scaling in CGESVD can be switched off.
363*> 3. Other comments related to code optimization are given in comments in the
364*> code, enclosed in [[double brackets]].
365*> \endverbatim
366*
367*> \par Bugs, examples and comments
368* ===========================
369*
370*> \verbatim
371*> Please report all bugs and send interesting examples and/or comments to
372*> drmac@math.hr. Thank you.
373*> \endverbatim
374*
375*> \par References
376* ===============
377*
378*> \verbatim
379*> [1] Zlatko Drmac, Algorithm 977: A QR-Preconditioned QR SVD Method for
380*> Computing the SVD with High Accuracy. ACM Trans. Math. Softw.
381*> 44(1): 11:1-11:30 (2017)
382*>
383*> SIGMA library, xGESVDQ section updated February 2016.
384*> Developed and coded by Zlatko Drmac, Department of Mathematics
385*> University of Zagreb, Croatia, drmac@math.hr
386*> \endverbatim
387*
388*
389*> \par Contributors:
390* ==================
391*>
392*> \verbatim
393*> Developed and coded by Zlatko Drmac, Department of Mathematics
394*> University of Zagreb, Croatia, drmac@math.hr
395*> \endverbatim
396*
397* Authors:
398* ========
399*
400*> \author Univ. of Tennessee
401*> \author Univ. of California Berkeley
402*> \author Univ. of Colorado Denver
403*> \author NAG Ltd.
404*
405*> \ingroup gesvdq
406*
407* =====================================================================
408 SUBROUTINE zgesvdq( JOBA, JOBP, JOBR, JOBU, JOBV, M, N, A, LDA,
409 $ S, U, LDU, V, LDV, NUMRANK, IWORK, LIWORK,
410 $ CWORK, LCWORK, RWORK, LRWORK, INFO )
411* .. Scalar Arguments ..
412 IMPLICIT NONE
413 CHARACTER JOBA, JOBP, JOBR, JOBU, JOBV
414 INTEGER M, N, LDA, LDU, LDV, NUMRANK, LIWORK, LCWORK, LRWORK,
415 $ info
416* ..
417* .. Array Arguments ..
418 COMPLEX*16 A( LDA, * ), U( LDU, * ), V( LDV, * ), CWORK( * )
419 DOUBLE PRECISION S( * ), RWORK( * )
420 INTEGER IWORK( * )
421*
422* =====================================================================
423*
424* .. Parameters ..
425 DOUBLE PRECISION ZERO, ONE
426 PARAMETER ( ZERO = 0.0d0, one = 1.0d0 )
427 COMPLEX*16 CZERO, CONE
428 parameter( czero = (0.0d0,0.0d0), cone = (1.0d0,0.0d0) )
429* ..
430* .. Local Scalars ..
431 INTEGER IERR, NR, N1, OPTRATIO, p, q
432 INTEGER LWCON, LWQP3, LWRK_ZGELQF, LWRK_ZGESVD, LWRK_ZGESVD2,
433 $ lwrk_zgeqp3, lwrk_zgeqrf, lwrk_zunmlq, lwrk_zunmqr,
434 $ lwrk_zunmqr2, lwlqf, lwqrf, lwsvd, lwsvd2, lwunq,
435 $ lwunq2, lwunlq, minwrk, minwrk2, optwrk, optwrk2,
436 $ iminwrk, rminwrk
437 LOGICAL ACCLA, ACCLM, ACCLH, ASCALED, CONDA, DNTWU, DNTWV,
438 $ LQUERY, LSVC0, LSVEC, ROWPRM, RSVEC, RTRANS, WNTUA,
439 $ wntuf, wntur, wntus, wntva, wntvr
440 DOUBLE PRECISION BIG, EPSLN, RTMP, SCONDA, SFMIN
441 COMPLEX*16 CTMP
442* ..
443* .. Local Arrays
444 COMPLEX*16 CDUMMY(1)
445 DOUBLE PRECISION RDUMMY(1)
446* ..
447* .. External Subroutines (BLAS, LAPACK)
448 EXTERNAL zgelqf, zgeqp3, zgeqrf, zgesvd, zlacpy,
449 $ zlapmt,
452* ..
453* .. External Functions (BLAS, LAPACK)
454 LOGICAL LSAME
455 INTEGER IDAMAX
456 DOUBLE PRECISION ZLANGE, DZNRM2, DLAMCH
457 EXTERNAL lsame, zlange, idamax, dznrm2, dlamch
458* ..
459* .. Intrinsic Functions ..
460 INTRINSIC abs, conjg, max, min, dble, sqrt
461* ..
462* .. Executable Statements ..
463*
464* Test the input arguments
465*
466 wntus = lsame( jobu, 'S' ) .OR. lsame( jobu, 'U' )
467 wntur = lsame( jobu, 'R' )
468 wntua = lsame( jobu, 'A' )
469 wntuf = lsame( jobu, 'F' )
470 lsvc0 = wntus .OR. wntur .OR. wntua
471 lsvec = lsvc0 .OR. wntuf
472 dntwu = lsame( jobu, 'N' )
473*
474 wntvr = lsame( jobv, 'R' )
475 wntva = lsame( jobv, 'A' ) .OR. lsame( jobv, 'V' )
476 rsvec = wntvr .OR. wntva
477 dntwv = lsame( jobv, 'N' )
478*
479 accla = lsame( joba, 'A' )
480 acclm = lsame( joba, 'M' )
481 conda = lsame( joba, 'E' )
482 acclh = lsame( joba, 'H' ) .OR. conda
483*
484 rowprm = lsame( jobp, 'P' )
485 rtrans = lsame( jobr, 'T' )
486*
487 IF ( rowprm ) THEN
488 iminwrk = max( 1, n + m - 1 )
489 rminwrk = max( 2, m, 5*n )
490 ELSE
491 iminwrk = max( 1, n )
492 rminwrk = max( 2, 5*n )
493 END IF
494 lquery = (liwork .EQ. -1 .OR. lcwork .EQ. -1 .OR. lrwork .EQ. -1)
495 info = 0
496 IF ( .NOT. ( accla .OR. acclm .OR. acclh ) ) THEN
497 info = -1
498 ELSE IF ( .NOT.( rowprm .OR. lsame( jobp, 'N' ) ) ) THEN
499 info = -2
500 ELSE IF ( .NOT.( rtrans .OR. lsame( jobr, 'N' ) ) ) THEN
501 info = -3
502 ELSE IF ( .NOT.( lsvec .OR. dntwu ) ) THEN
503 info = -4
504 ELSE IF ( wntur .AND. wntva ) THEN
505 info = -5
506 ELSE IF ( .NOT.( rsvec .OR. dntwv )) THEN
507 info = -5
508 ELSE IF ( m.LT.0 ) THEN
509 info = -6
510 ELSE IF ( ( n.LT.0 ) .OR. ( n.GT.m ) ) THEN
511 info = -7
512 ELSE IF ( lda.LT.max( 1, m ) ) THEN
513 info = -9
514 ELSE IF ( ldu.LT.1 .OR. ( lsvc0 .AND. ldu.LT.m ) .OR.
515 $ ( wntuf .AND. ldu.LT.n ) ) THEN
516 info = -12
517 ELSE IF ( ldv.LT.1 .OR. ( rsvec .AND. ldv.LT.n ) .OR.
518 $ ( conda .AND. ldv.LT.n ) ) THEN
519 info = -14
520 ELSE IF ( liwork .LT. iminwrk .AND. .NOT. lquery ) THEN
521 info = -17
522 END IF
523*
524*
525 IF ( info .EQ. 0 ) THEN
526* .. compute the minimal and the optimal workspace lengths
527* [[The expressions for computing the minimal and the optimal
528* values of LCWORK are written with a lot of redundancy and
529* can be simplified. However, this detailed form is easier for
530* maintenance and modifications of the code.]]
531*
532* .. minimal workspace length for ZGEQP3 of an M x N matrix
533 lwqp3 = n+1
534* .. minimal workspace length for ZUNMQR to build left singular vectors
535 IF ( wntus .OR. wntur ) THEN
536 lwunq = max( n , 1 )
537 ELSE IF ( wntua ) THEN
538 lwunq = max( m , 1 )
539 END IF
540* .. minimal workspace length for ZPOCON of an N x N matrix
541 lwcon = 2 * n
542* .. ZGESVD of an N x N matrix
543 lwsvd = max( 3 * n, 1 )
544 IF ( lquery ) THEN
545 CALL zgeqp3( m, n, a, lda, iwork, cdummy, cdummy, -1,
546 $ rdummy, ierr )
547 lwrk_zgeqp3 = int( cdummy(1) )
548 IF ( wntus .OR. wntur ) THEN
549 CALL zunmqr( 'L', 'N', m, n, n, a, lda, cdummy, u,
550 $ ldu, cdummy, -1, ierr )
551 lwrk_zunmqr = int( cdummy(1) )
552 ELSE IF ( wntua ) THEN
553 CALL zunmqr( 'L', 'N', m, m, n, a, lda, cdummy, u,
554 $ ldu, cdummy, -1, ierr )
555 lwrk_zunmqr = int( cdummy(1) )
556 ELSE
557 lwrk_zunmqr = 0
558 END IF
559 END IF
560 minwrk = 2
561 optwrk = 2
562 IF ( .NOT. (lsvec .OR. rsvec ) ) THEN
563* .. minimal and optimal sizes of the complex workspace if
564* only the singular values are requested
565 IF ( conda ) THEN
566 minwrk = max( n+lwqp3, lwcon, lwsvd )
567 ELSE
568 minwrk = max( n+lwqp3, lwsvd )
569 END IF
570 IF ( lquery ) THEN
571 CALL zgesvd( 'N', 'N', n, n, a, lda, s, u, ldu,
572 $ v, ldv, cdummy, -1, rdummy, ierr )
573 lwrk_zgesvd = int( cdummy(1) )
574 IF ( conda ) THEN
575 optwrk = max( n+lwrk_zgeqp3, n+lwcon, lwrk_zgesvd )
576 ELSE
577 optwrk = max( n+lwrk_zgeqp3, lwrk_zgesvd )
578 END IF
579 END IF
580 ELSE IF ( lsvec .AND. (.NOT.rsvec) ) THEN
581* .. minimal and optimal sizes of the complex workspace if the
582* singular values and the left singular vectors are requested
583 IF ( conda ) THEN
584 minwrk = n + max( lwqp3, lwcon, lwsvd, lwunq )
585 ELSE
586 minwrk = n + max( lwqp3, lwsvd, lwunq )
587 END IF
588 IF ( lquery ) THEN
589 IF ( rtrans ) THEN
590 CALL zgesvd( 'N', 'O', n, n, a, lda, s, u, ldu,
591 $ v, ldv, cdummy, -1, rdummy, ierr )
592 ELSE
593 CALL zgesvd( 'O', 'N', n, n, a, lda, s, u, ldu,
594 $ v, ldv, cdummy, -1, rdummy, ierr )
595 END IF
596 lwrk_zgesvd = int( cdummy(1) )
597 IF ( conda ) THEN
598 optwrk = n + max( lwrk_zgeqp3, lwcon, lwrk_zgesvd,
599 $ lwrk_zunmqr )
600 ELSE
601 optwrk = n + max( lwrk_zgeqp3, lwrk_zgesvd,
602 $ lwrk_zunmqr )
603 END IF
604 END IF
605 ELSE IF ( rsvec .AND. (.NOT.lsvec) ) THEN
606* .. minimal and optimal sizes of the complex workspace if the
607* singular values and the right singular vectors are requested
608 IF ( conda ) THEN
609 minwrk = n + max( lwqp3, lwcon, lwsvd )
610 ELSE
611 minwrk = n + max( lwqp3, lwsvd )
612 END IF
613 IF ( lquery ) THEN
614 IF ( rtrans ) THEN
615 CALL zgesvd( 'O', 'N', n, n, a, lda, s, u, ldu,
616 $ v, ldv, cdummy, -1, rdummy, ierr )
617 ELSE
618 CALL zgesvd( 'N', 'O', n, n, a, lda, s, u, ldu,
619 $ v, ldv, cdummy, -1, rdummy, ierr )
620 END IF
621 lwrk_zgesvd = int( cdummy(1) )
622 IF ( conda ) THEN
623 optwrk = n + max( lwrk_zgeqp3, lwcon, lwrk_zgesvd )
624 ELSE
625 optwrk = n + max( lwrk_zgeqp3, lwrk_zgesvd )
626 END IF
627 END IF
628 ELSE
629* .. minimal and optimal sizes of the complex workspace if the
630* full SVD is requested
631 IF ( rtrans ) THEN
632 minwrk = max( lwqp3, lwsvd, lwunq )
633 IF ( conda ) minwrk = max( minwrk, lwcon )
634 minwrk = minwrk + n
635 IF ( wntva ) THEN
636* .. minimal workspace length for N x N/2 ZGEQRF
637 lwqrf = max( n/2, 1 )
638* .. minimal workspace length for N/2 x N/2 ZGESVD
639 lwsvd2 = max( 3 * (n/2), 1 )
640 lwunq2 = max( n, 1 )
641 minwrk2 = max( lwqp3, n/2+lwqrf, n/2+lwsvd2,
642 $ n/2+lwunq2, lwunq )
643 IF ( conda ) minwrk2 = max( minwrk2, lwcon )
644 minwrk2 = n + minwrk2
645 minwrk = max( minwrk, minwrk2 )
646 END IF
647 ELSE
648 minwrk = max( lwqp3, lwsvd, lwunq )
649 IF ( conda ) minwrk = max( minwrk, lwcon )
650 minwrk = minwrk + n
651 IF ( wntva ) THEN
652* .. minimal workspace length for N/2 x N ZGELQF
653 lwlqf = max( n/2, 1 )
654 lwsvd2 = max( 3 * (n/2), 1 )
655 lwunlq = max( n , 1 )
656 minwrk2 = max( lwqp3, n/2+lwlqf, n/2+lwsvd2,
657 $ n/2+lwunlq, lwunq )
658 IF ( conda ) minwrk2 = max( minwrk2, lwcon )
659 minwrk2 = n + minwrk2
660 minwrk = max( minwrk, minwrk2 )
661 END IF
662 END IF
663 IF ( lquery ) THEN
664 IF ( rtrans ) THEN
665 CALL zgesvd( 'O', 'A', n, n, a, lda, s, u, ldu,
666 $ v, ldv, cdummy, -1, rdummy, ierr )
667 lwrk_zgesvd = int( cdummy(1) )
668 optwrk = max(lwrk_zgeqp3,lwrk_zgesvd,lwrk_zunmqr)
669 IF ( conda ) optwrk = max( optwrk, lwcon )
670 optwrk = n + optwrk
671 IF ( wntva ) THEN
672 CALL zgeqrf(n,n/2,u,ldu,cdummy,cdummy,-1,ierr)
673 lwrk_zgeqrf = int( cdummy(1) )
674 CALL zgesvd( 'S', 'O', n/2,n/2, v,ldv, s, u,
675 $ ldu,
676 $ v, ldv, cdummy, -1, rdummy, ierr )
677 lwrk_zgesvd2 = int( cdummy(1) )
678 CALL zunmqr( 'R', 'C', n, n, n/2, u, ldu,
679 $ cdummy,
680 $ v, ldv, cdummy, -1, ierr )
681 lwrk_zunmqr2 = int( cdummy(1) )
682 optwrk2 = max( lwrk_zgeqp3, n/2+lwrk_zgeqrf,
683 $ n/2+lwrk_zgesvd2, n/2+lwrk_zunmqr2 )
684 IF ( conda ) optwrk2 = max( optwrk2, lwcon )
685 optwrk2 = n + optwrk2
686 optwrk = max( optwrk, optwrk2 )
687 END IF
688 ELSE
689 CALL zgesvd( 'S', 'O', n, n, a, lda, s, u, ldu,
690 $ v, ldv, cdummy, -1, rdummy, ierr )
691 lwrk_zgesvd = int( cdummy(1) )
692 optwrk = max(lwrk_zgeqp3,lwrk_zgesvd,lwrk_zunmqr)
693 IF ( conda ) optwrk = max( optwrk, lwcon )
694 optwrk = n + optwrk
695 IF ( wntva ) THEN
696 CALL zgelqf(n/2,n,u,ldu,cdummy,cdummy,-1,ierr)
697 lwrk_zgelqf = int( cdummy(1) )
698 CALL zgesvd( 'S','O', n/2,n/2, v, ldv, s, u,
699 $ ldu,
700 $ v, ldv, cdummy, -1, rdummy, ierr )
701 lwrk_zgesvd2 = int( cdummy(1) )
702 CALL zunmlq( 'R', 'N', n, n, n/2, u, ldu,
703 $ cdummy,
704 $ v, ldv, cdummy,-1,ierr )
705 lwrk_zunmlq = int( cdummy(1) )
706 optwrk2 = max( lwrk_zgeqp3, n/2+lwrk_zgelqf,
707 $ n/2+lwrk_zgesvd2, n/2+lwrk_zunmlq )
708 IF ( conda ) optwrk2 = max( optwrk2, lwcon )
709 optwrk2 = n + optwrk2
710 optwrk = max( optwrk, optwrk2 )
711 END IF
712 END IF
713 END IF
714 END IF
715*
716 minwrk = max( 2, minwrk )
717 optwrk = max( 2, optwrk )
718 IF ( lcwork .LT. minwrk .AND. (.NOT.lquery) ) info = -19
719*
720 END IF
721*
722 IF (info .EQ. 0 .AND. lrwork .LT. rminwrk .AND. .NOT. lquery) THEN
723 info = -21
724 END IF
725 IF( info.NE.0 ) THEN
726 CALL xerbla( 'ZGESVDQ', -info )
727 RETURN
728 ELSE IF ( lquery ) THEN
729*
730* Return optimal workspace
731*
732 iwork(1) = iminwrk
733 cwork(1) = optwrk
734 cwork(2) = minwrk
735 rwork(1) = rminwrk
736 RETURN
737 END IF
738*
739* Quick return if the matrix is void.
740*
741 IF( ( m.EQ.0 ) .OR. ( n.EQ.0 ) ) THEN
742* .. all output is void.
743 RETURN
744 END IF
745*
746 big = dlamch('O')
747 ascaled = .false.
748 IF ( rowprm ) THEN
749* .. reordering the rows in decreasing sequence in the
750* ell-infinity norm - this enhances numerical robustness in
751* the case of differently scaled rows.
752 DO 1904 p = 1, m
753* RWORK(p) = ABS( A(p,IZAMAX(N,A(p,1),LDA)) )
754* [[ZLANGE will return NaN if an entry of the p-th row is Nan]]
755 rwork(p) = zlange( 'M', 1, n, a(p,1), lda, rdummy )
756* .. check for NaN's and Inf's
757 IF ( ( rwork(p) .NE. rwork(p) ) .OR.
758 $ ( (rwork(p)*zero) .NE. zero ) ) THEN
759 info = -8
760 CALL xerbla( 'ZGESVDQ', -info )
761 RETURN
762 END IF
763 1904 CONTINUE
764 DO 1952 p = 1, m - 1
765 q = idamax( m-p+1, rwork(p), 1 ) + p - 1
766 iwork(n+p) = q
767 IF ( p .NE. q ) THEN
768 rtmp = rwork(p)
769 rwork(p) = rwork(q)
770 rwork(q) = rtmp
771 END IF
772 1952 CONTINUE
773*
774 IF ( rwork(1) .EQ. zero ) THEN
775* Quick return: A is the M x N zero matrix.
776 numrank = 0
777 CALL dlaset( 'G', n, 1, zero, zero, s, n )
778 IF ( wntus ) CALL zlaset('G', m, n, czero, cone, u,
779 $ ldu)
780 IF ( wntua ) CALL zlaset('G', m, m, czero, cone, u,
781 $ ldu)
782 IF ( wntva ) CALL zlaset('G', n, n, czero, cone, v,
783 $ ldv)
784 IF ( wntuf ) THEN
785 CALL zlaset( 'G', n, 1, czero, czero, cwork, n )
786 CALL zlaset( 'G', m, n, czero, cone, u, ldu )
787 END IF
788 DO 5001 p = 1, n
789 iwork(p) = p
790 5001 CONTINUE
791 IF ( rowprm ) THEN
792 DO 5002 p = n + 1, n + m - 1
793 iwork(p) = p - n
794 5002 CONTINUE
795 END IF
796 IF ( conda ) rwork(1) = -1
797 rwork(2) = -1
798 RETURN
799 END IF
800*
801 IF ( rwork(1) .GT. big / sqrt(dble(m)) ) THEN
802* .. to prevent overflow in the QR factorization, scale the
803* matrix by 1/sqrt(M) if too large entry detected
804 CALL zlascl('G',0,0,sqrt(dble(m)),one, m,n, a,lda,
805 $ ierr)
806 ascaled = .true.
807 END IF
808 CALL zlaswp( n, a, lda, 1, m-1, iwork(n+1), 1 )
809 END IF
810*
811* .. At this stage, preemptive scaling is done only to avoid column
812* norms overflows during the QR factorization. The SVD procedure should
813* have its own scaling to save the singular values from overflows and
814* underflows. That depends on the SVD procedure.
815*
816 IF ( .NOT.rowprm ) THEN
817 rtmp = zlange( 'M', m, n, a, lda, rwork )
818 IF ( ( rtmp .NE. rtmp ) .OR.
819 $ ( (rtmp*zero) .NE. zero ) ) THEN
820 info = -8
821 CALL xerbla( 'ZGESVDQ', -info )
822 RETURN
823 END IF
824 IF ( rtmp .GT. big / sqrt(dble(m)) ) THEN
825* .. to prevent overflow in the QR factorization, scale the
826* matrix by 1/sqrt(M) if too large entry detected
827 CALL zlascl('G',0,0, sqrt(dble(m)),one, m,n, a,lda,
828 $ ierr)
829 ascaled = .true.
830 END IF
831 END IF
832*
833* .. QR factorization with column pivoting
834*
835* A * P = Q * [ R ]
836* [ 0 ]
837*
838 DO 1963 p = 1, n
839* .. all columns are free columns
840 iwork(p) = 0
841 1963 CONTINUE
842 CALL zgeqp3( m, n, a, lda, iwork, cwork, cwork(n+1), lcwork-n,
843 $ rwork, ierr )
844*
845* If the user requested accuracy level allows truncation in the
846* computed upper triangular factor, the matrix R is examined and,
847* if possible, replaced with its leading upper trapezoidal part.
848*
849 epsln = dlamch('E')
850 sfmin = dlamch('S')
851* SMALL = SFMIN / EPSLN
852 nr = n
853*
854 IF ( accla ) THEN
855*
856* Standard absolute error bound suffices. All sigma_i with
857* sigma_i < N*EPS*||A||_F are flushed to zero. This is an
858* aggressive enforcement of lower numerical rank by introducing a
859* backward error of the order of N*EPS*||A||_F.
860 nr = 1
861 rtmp = sqrt(dble(n))*epsln
862 DO 3001 p = 2, n
863 IF ( abs(a(p,p)) .LT. (rtmp*abs(a(1,1))) ) GO TO 3002
864 nr = nr + 1
865 3001 CONTINUE
866 3002 CONTINUE
867*
868 ELSEIF ( acclm ) THEN
869* .. similarly as above, only slightly more gentle (less aggressive).
870* Sudden drop on the diagonal of R is used as the criterion for being
871* close-to-rank-deficient. The threshold is set to EPSLN=DLAMCH('E').
872* [[This can be made more flexible by replacing this hard-coded value
873* with a user specified threshold.]] Also, the values that underflow
874* will be truncated.
875 nr = 1
876 DO 3401 p = 2, n
877 IF ( ( abs(a(p,p)) .LT. (epsln*abs(a(p-1,p-1))) ) .OR.
878 $ ( abs(a(p,p)) .LT. sfmin ) ) GO TO 3402
879 nr = nr + 1
880 3401 CONTINUE
881 3402 CONTINUE
882*
883 ELSE
884* .. RRQR not authorized to determine numerical rank except in the
885* obvious case of zero pivots.
886* .. inspect R for exact zeros on the diagonal;
887* R(i,i)=0 => R(i:N,i:N)=0.
888 nr = 1
889 DO 3501 p = 2, n
890 IF ( abs(a(p,p)) .EQ. zero ) GO TO 3502
891 nr = nr + 1
892 3501 CONTINUE
893 3502 CONTINUE
894*
895 IF ( conda ) THEN
896* Estimate the scaled condition number of A. Use the fact that it is
897* the same as the scaled condition number of R.
898* .. V is used as workspace
899 CALL zlacpy( 'U', n, n, a, lda, v, ldv )
900* Only the leading NR x NR submatrix of the triangular factor
901* is considered. Only if NR=N will this give a reliable error
902* bound. However, even for NR < N, this can be used on an
903* expert level and obtain useful information in the sense of
904* perturbation theory.
905 DO 3053 p = 1, nr
906 rtmp = dznrm2( p, v(1,p), 1 )
907 CALL zdscal( p, one/rtmp, v(1,p), 1 )
908 3053 CONTINUE
909 IF ( .NOT. ( lsvec .OR. rsvec ) ) THEN
910 CALL zpocon( 'U', nr, v, ldv, one, rtmp,
911 $ cwork, rwork, ierr )
912 ELSE
913 CALL zpocon( 'U', nr, v, ldv, one, rtmp,
914 $ cwork(n+1), rwork, ierr )
915 END IF
916 sconda = one / sqrt(rtmp)
917* For NR=N, SCONDA is an estimate of SQRT(||(R^* * R)^(-1)||_1),
918* N^(-1/4) * SCONDA <= ||R^(-1)||_2 <= N^(1/4) * SCONDA
919* See the reference [1] for more details.
920 END IF
921*
922 ENDIF
923*
924 IF ( wntur ) THEN
925 n1 = nr
926 ELSE IF ( wntus .OR. wntuf) THEN
927 n1 = n
928 ELSE IF ( wntua ) THEN
929 n1 = m
930 END IF
931*
932 IF ( .NOT. ( rsvec .OR. lsvec ) ) THEN
933*.......................................................................
934* .. only the singular values are requested
935*.......................................................................
936 IF ( rtrans ) THEN
937*
938* .. compute the singular values of R**H = [A](1:NR,1:N)**H
939* .. set the lower triangle of [A] to [A](1:NR,1:N)**H and
940* the upper triangle of [A] to zero.
941 DO 1146 p = 1, min( n, nr )
942 a(p,p) = conjg(a(p,p))
943 DO 1147 q = p + 1, n
944 a(q,p) = conjg(a(p,q))
945 IF ( q .LE. nr ) a(p,q) = czero
946 1147 CONTINUE
947 1146 CONTINUE
948*
949 CALL zgesvd( 'N', 'N', n, nr, a, lda, s, u, ldu,
950 $ v, ldv, cwork, lcwork, rwork, info )
951*
952 ELSE
953*
954* .. compute the singular values of R = [A](1:NR,1:N)
955*
956 IF ( nr .GT. 1 )
957 $ CALL zlaset( 'L', nr-1,nr-1, czero,czero, a(2,1),
958 $ lda )
959 CALL zgesvd( 'N', 'N', nr, n, a, lda, s, u, ldu,
960 $ v, ldv, cwork, lcwork, rwork, info )
961*
962 END IF
963*
964 ELSE IF ( lsvec .AND. ( .NOT. rsvec) ) THEN
965*.......................................................................
966* .. the singular values and the left singular vectors requested
967*.......................................................................""""""""
968 IF ( rtrans ) THEN
969* .. apply ZGESVD to R**H
970* .. copy R**H into [U] and overwrite [U] with the right singular
971* vectors of R
972 DO 1192 p = 1, nr
973 DO 1193 q = p, n
974 u(q,p) = conjg(a(p,q))
975 1193 CONTINUE
976 1192 CONTINUE
977 IF ( nr .GT. 1 )
978 $ CALL zlaset( 'U', nr-1,nr-1, czero,czero, u(1,2),
979 $ ldu )
980* .. the left singular vectors not computed, the NR right singular
981* vectors overwrite [U](1:NR,1:NR) as conjugate transposed. These
982* will be pre-multiplied by Q to build the left singular vectors of A.
983 CALL zgesvd( 'N', 'O', n, nr, u, ldu, s, u, ldu,
984 $ u, ldu, cwork(n+1), lcwork-n, rwork, info )
985*
986 DO 1119 p = 1, nr
987 u(p,p) = conjg(u(p,p))
988 DO 1120 q = p + 1, nr
989 ctmp = conjg(u(q,p))
990 u(q,p) = conjg(u(p,q))
991 u(p,q) = ctmp
992 1120 CONTINUE
993 1119 CONTINUE
994*
995 ELSE
996* .. apply ZGESVD to R
997* .. copy R into [U] and overwrite [U] with the left singular vectors
998 CALL zlacpy( 'U', nr, n, a, lda, u, ldu )
999 IF ( nr .GT. 1 )
1000 $ CALL zlaset( 'L', nr-1, nr-1, czero, czero, u(2,1),
1001 $ ldu )
1002* .. the right singular vectors not computed, the NR left singular
1003* vectors overwrite [U](1:NR,1:NR)
1004 CALL zgesvd( 'O', 'N', nr, n, u, ldu, s, u, ldu,
1005 $ v, ldv, cwork(n+1), lcwork-n, rwork, info )
1006* .. now [U](1:NR,1:NR) contains the NR left singular vectors of
1007* R. These will be pre-multiplied by Q to build the left singular
1008* vectors of A.
1009 END IF
1010*
1011* .. assemble the left singular vector matrix U of dimensions
1012* (M x NR) or (M x N) or (M x M).
1013 IF ( ( nr .LT. m ) .AND. ( .NOT.wntuf ) ) THEN
1014 CALL zlaset('A', m-nr, nr, czero, czero, u(nr+1,1), ldu)
1015 IF ( nr .LT. n1 ) THEN
1016 CALL zlaset( 'A',nr,n1-nr,czero,czero,u(1,nr+1),
1017 $ ldu )
1018 CALL zlaset( 'A',m-nr,n1-nr,czero,cone,
1019 $ u(nr+1,nr+1), ldu )
1020 END IF
1021 END IF
1022*
1023* The Q matrix from the first QRF is built into the left singular
1024* vectors matrix U.
1025*
1026 IF ( .NOT.wntuf )
1027 $ CALL zunmqr( 'L', 'N', m, n1, n, a, lda, cwork, u,
1028 $ ldu, cwork(n+1), lcwork-n, ierr )
1029 IF ( rowprm .AND. .NOT.wntuf )
1030 $ CALL zlaswp( n1, u, ldu, 1, m-1, iwork(n+1), -1 )
1031*
1032 ELSE IF ( rsvec .AND. ( .NOT. lsvec ) ) THEN
1033*.......................................................................
1034* .. the singular values and the right singular vectors requested
1035*.......................................................................
1036 IF ( rtrans ) THEN
1037* .. apply ZGESVD to R**H
1038* .. copy R**H into V and overwrite V with the left singular vectors
1039 DO 1165 p = 1, nr
1040 DO 1166 q = p, n
1041 v(q,p) = conjg(a(p,q))
1042 1166 CONTINUE
1043 1165 CONTINUE
1044 IF ( nr .GT. 1 )
1045 $ CALL zlaset( 'U', nr-1,nr-1, czero,czero, v(1,2),
1046 $ ldv )
1047* .. the left singular vectors of R**H overwrite V, the right singular
1048* vectors not computed
1049 IF ( wntvr .OR. ( nr .EQ. n ) ) THEN
1050 CALL zgesvd( 'O', 'N', n, nr, v, ldv, s, u, ldu,
1051 $ u, ldu, cwork(n+1), lcwork-n, rwork, info )
1052*
1053 DO 1121 p = 1, nr
1054 v(p,p) = conjg(v(p,p))
1055 DO 1122 q = p + 1, nr
1056 ctmp = conjg(v(q,p))
1057 v(q,p) = conjg(v(p,q))
1058 v(p,q) = ctmp
1059 1122 CONTINUE
1060 1121 CONTINUE
1061*
1062 IF ( nr .LT. n ) THEN
1063 DO 1103 p = 1, nr
1064 DO 1104 q = nr + 1, n
1065 v(p,q) = conjg(v(q,p))
1066 1104 CONTINUE
1067 1103 CONTINUE
1068 END IF
1069 CALL zlapmt( .false., nr, n, v, ldv, iwork )
1070 ELSE
1071* .. need all N right singular vectors and NR < N
1072* [!] This is simple implementation that augments [V](1:N,1:NR)
1073* by padding a zero block. In the case NR << N, a more efficient
1074* way is to first use the QR factorization. For more details
1075* how to implement this, see the " FULL SVD " branch.
1076 CALL zlaset('G', n, n-nr, czero, czero, v(1,nr+1),
1077 $ ldv)
1078 CALL zgesvd( 'O', 'N', n, n, v, ldv, s, u, ldu,
1079 $ u, ldu, cwork(n+1), lcwork-n, rwork, info )
1080*
1081 DO 1123 p = 1, n
1082 v(p,p) = conjg(v(p,p))
1083 DO 1124 q = p + 1, n
1084 ctmp = conjg(v(q,p))
1085 v(q,p) = conjg(v(p,q))
1086 v(p,q) = ctmp
1087 1124 CONTINUE
1088 1123 CONTINUE
1089 CALL zlapmt( .false., n, n, v, ldv, iwork )
1090 END IF
1091*
1092 ELSE
1093* .. aply ZGESVD to R
1094* .. copy R into V and overwrite V with the right singular vectors
1095 CALL zlacpy( 'U', nr, n, a, lda, v, ldv )
1096 IF ( nr .GT. 1 )
1097 $ CALL zlaset( 'L', nr-1, nr-1, czero, czero, v(2,1),
1098 $ ldv )
1099* .. the right singular vectors overwrite V, the NR left singular
1100* vectors stored in U(1:NR,1:NR)
1101 IF ( wntvr .OR. ( nr .EQ. n ) ) THEN
1102 CALL zgesvd( 'N', 'O', nr, n, v, ldv, s, u, ldu,
1103 $ v, ldv, cwork(n+1), lcwork-n, rwork, info )
1104 CALL zlapmt( .false., nr, n, v, ldv, iwork )
1105* .. now [V](1:NR,1:N) contains V(1:N,1:NR)**H
1106 ELSE
1107* .. need all N right singular vectors and NR < N
1108* [!] This is simple implementation that augments [V](1:NR,1:N)
1109* by padding a zero block. In the case NR << N, a more efficient
1110* way is to first use the LQ factorization. For more details
1111* how to implement this, see the " FULL SVD " branch.
1112 CALL zlaset('G', n-nr, n, czero,czero, v(nr+1,1),
1113 $ ldv)
1114 CALL zgesvd( 'N', 'O', n, n, v, ldv, s, u, ldu,
1115 $ v, ldv, cwork(n+1), lcwork-n, rwork, info )
1116 CALL zlapmt( .false., n, n, v, ldv, iwork )
1117 END IF
1118* .. now [V] contains the adjoint of the matrix of the right singular
1119* vectors of A.
1120 END IF
1121*
1122 ELSE
1123*.......................................................................
1124* .. FULL SVD requested
1125*.......................................................................
1126 IF ( rtrans ) THEN
1127*
1128* .. apply ZGESVD to R**H [[this option is left for R&D&T]]
1129*
1130 IF ( wntvr .OR. ( nr .EQ. n ) ) THEN
1131* .. copy R**H into [V] and overwrite [V] with the left singular
1132* vectors of R**H
1133 DO 1168 p = 1, nr
1134 DO 1169 q = p, n
1135 v(q,p) = conjg(a(p,q))
1136 1169 CONTINUE
1137 1168 CONTINUE
1138 IF ( nr .GT. 1 )
1139 $ CALL zlaset( 'U', nr-1,nr-1, czero,czero, v(1,2),
1140 $ ldv )
1141*
1142* .. the left singular vectors of R**H overwrite [V], the NR right
1143* singular vectors of R**H stored in [U](1:NR,1:NR) as conjugate
1144* transposed
1145 CALL zgesvd( 'O', 'A', n, nr, v, ldv, s, v, ldv,
1146 $ u, ldu, cwork(n+1), lcwork-n, rwork, info )
1147* .. assemble V
1148 DO 1115 p = 1, nr
1149 v(p,p) = conjg(v(p,p))
1150 DO 1116 q = p + 1, nr
1151 ctmp = conjg(v(q,p))
1152 v(q,p) = conjg(v(p,q))
1153 v(p,q) = ctmp
1154 1116 CONTINUE
1155 1115 CONTINUE
1156 IF ( nr .LT. n ) THEN
1157 DO 1101 p = 1, nr
1158 DO 1102 q = nr+1, n
1159 v(p,q) = conjg(v(q,p))
1160 1102 CONTINUE
1161 1101 CONTINUE
1162 END IF
1163 CALL zlapmt( .false., nr, n, v, ldv, iwork )
1164*
1165 DO 1117 p = 1, nr
1166 u(p,p) = conjg(u(p,p))
1167 DO 1118 q = p + 1, nr
1168 ctmp = conjg(u(q,p))
1169 u(q,p) = conjg(u(p,q))
1170 u(p,q) = ctmp
1171 1118 CONTINUE
1172 1117 CONTINUE
1173*
1174 IF ( ( nr .LT. m ) .AND. .NOT.(wntuf)) THEN
1175 CALL zlaset('A', m-nr,nr, czero,czero, u(nr+1,1),
1176 $ ldu)
1177 IF ( nr .LT. n1 ) THEN
1178 CALL zlaset('A',nr,n1-nr,czero,czero,u(1,nr+1),
1179 $ ldu)
1180 CALL zlaset( 'A',m-nr,n1-nr,czero,cone,
1181 $ u(nr+1,nr+1), ldu )
1182 END IF
1183 END IF
1184*
1185 ELSE
1186* .. need all N right singular vectors and NR < N
1187* .. copy R**H into [V] and overwrite [V] with the left singular
1188* vectors of R**H
1189* [[The optimal ratio N/NR for using QRF instead of padding
1190* with zeros. Here hard coded to 2; it must be at least
1191* two due to work space constraints.]]
1192* OPTRATIO = ILAENV(6, 'ZGESVD', 'S' // 'O', NR,N,0,0)
1193* OPTRATIO = MAX( OPTRATIO, 2 )
1194 optratio = 2
1195 IF ( optratio*nr .GT. n ) THEN
1196 DO 1198 p = 1, nr
1197 DO 1199 q = p, n
1198 v(q,p) = conjg(a(p,q))
1199 1199 CONTINUE
1200 1198 CONTINUE
1201 IF ( nr .GT. 1 )
1202 $ CALL zlaset('U',nr-1,nr-1, czero,czero, v(1,2),
1203 $ ldv)
1204*
1205 CALL zlaset('A',n,n-nr,czero,czero,v(1,nr+1),ldv)
1206 CALL zgesvd( 'O', 'A', n, n, v, ldv, s, v, ldv,
1207 $ u, ldu, cwork(n+1), lcwork-n, rwork, info )
1208*
1209 DO 1113 p = 1, n
1210 v(p,p) = conjg(v(p,p))
1211 DO 1114 q = p + 1, n
1212 ctmp = conjg(v(q,p))
1213 v(q,p) = conjg(v(p,q))
1214 v(p,q) = ctmp
1215 1114 CONTINUE
1216 1113 CONTINUE
1217 CALL zlapmt( .false., n, n, v, ldv, iwork )
1218* .. assemble the left singular vector matrix U of dimensions
1219* (M x N1), i.e. (M x N) or (M x M).
1220*
1221 DO 1111 p = 1, n
1222 u(p,p) = conjg(u(p,p))
1223 DO 1112 q = p + 1, n
1224 ctmp = conjg(u(q,p))
1225 u(q,p) = conjg(u(p,q))
1226 u(p,q) = ctmp
1227 1112 CONTINUE
1228 1111 CONTINUE
1229*
1230 IF ( ( n .LT. m ) .AND. .NOT.(wntuf)) THEN
1231 CALL zlaset('A',m-n,n,czero,czero,u(n+1,1),ldu)
1232 IF ( n .LT. n1 ) THEN
1233 CALL zlaset('A',n,n1-n,czero,czero,u(1,n+1),
1234 $ ldu)
1235 CALL zlaset('A',m-n,n1-n,czero,cone,
1236 $ u(n+1,n+1), ldu )
1237 END IF
1238 END IF
1239 ELSE
1240* .. copy R**H into [U] and overwrite [U] with the right
1241* singular vectors of R
1242 DO 1196 p = 1, nr
1243 DO 1197 q = p, n
1244 u(q,nr+p) = conjg(a(p,q))
1245 1197 CONTINUE
1246 1196 CONTINUE
1247 IF ( nr .GT. 1 )
1248 $ CALL zlaset('U',nr-1,nr-1,czero,czero,u(1,nr+2),
1249 $ ldu)
1250 CALL zgeqrf( n, nr, u(1,nr+1), ldu, cwork(n+1),
1251 $ cwork(n+nr+1), lcwork-n-nr, ierr )
1252 DO 1143 p = 1, nr
1253 DO 1144 q = 1, n
1254 v(q,p) = conjg(u(p,nr+q))
1255 1144 CONTINUE
1256 1143 CONTINUE
1257 CALL zlaset('U',nr-1,nr-1,czero,czero,v(1,2),ldv)
1258 CALL zgesvd( 'S', 'O', nr, nr, v, ldv, s, u, ldu,
1259 $ v,ldv, cwork(n+nr+1),lcwork-n-nr,rwork, info )
1260 CALL zlaset('A',n-nr,nr,czero,czero,v(nr+1,1),ldv)
1261 CALL zlaset('A',nr,n-nr,czero,czero,v(1,nr+1),ldv)
1262 CALL zlaset('A',n-nr,n-nr,czero,cone,v(nr+1,nr+1),
1263 $ ldv)
1264 CALL zunmqr('R','C', n, n, nr, u(1,nr+1), ldu,
1265 $ cwork(n+1),v,ldv,cwork(n+nr+1),lcwork-n-nr,ierr)
1266 CALL zlapmt( .false., n, n, v, ldv, iwork )
1267* .. assemble the left singular vector matrix U of dimensions
1268* (M x NR) or (M x N) or (M x M).
1269 IF ( ( nr .LT. m ) .AND. .NOT.(wntuf)) THEN
1270 CALL zlaset('A',m-nr,nr,czero,czero,u(nr+1,1),
1271 $ ldu)
1272 IF ( nr .LT. n1 ) THEN
1273 CALL zlaset('A',nr,n1-nr,czero,czero,u(1,nr+1),
1274 $ ldu)
1275 CALL zlaset( 'A',m-nr,n1-nr,czero,cone,
1276 $ u(nr+1,nr+1),ldu)
1277 END IF
1278 END IF
1279 END IF
1280 END IF
1281*
1282 ELSE
1283*
1284* .. apply ZGESVD to R [[this is the recommended option]]
1285*
1286 IF ( wntvr .OR. ( nr .EQ. n ) ) THEN
1287* .. copy R into [V] and overwrite V with the right singular vectors
1288 CALL zlacpy( 'U', nr, n, a, lda, v, ldv )
1289 IF ( nr .GT. 1 )
1290 $ CALL zlaset( 'L', nr-1,nr-1, czero,czero, v(2,1),
1291 $ ldv )
1292* .. the right singular vectors of R overwrite [V], the NR left
1293* singular vectors of R stored in [U](1:NR,1:NR)
1294 CALL zgesvd( 'S', 'O', nr, n, v, ldv, s, u, ldu,
1295 $ v, ldv, cwork(n+1), lcwork-n, rwork, info )
1296 CALL zlapmt( .false., nr, n, v, ldv, iwork )
1297* .. now [V](1:NR,1:N) contains V(1:N,1:NR)**H
1298* .. assemble the left singular vector matrix U of dimensions
1299* (M x NR) or (M x N) or (M x M).
1300 IF ( ( nr .LT. m ) .AND. .NOT.(wntuf)) THEN
1301 CALL zlaset('A', m-nr,nr, czero,czero, u(nr+1,1),
1302 $ ldu)
1303 IF ( nr .LT. n1 ) THEN
1304 CALL zlaset('A',nr,n1-nr,czero,czero,u(1,nr+1),
1305 $ ldu)
1306 CALL zlaset( 'A',m-nr,n1-nr,czero,cone,
1307 $ u(nr+1,nr+1), ldu )
1308 END IF
1309 END IF
1310*
1311 ELSE
1312* .. need all N right singular vectors and NR < N
1313* .. the requested number of the left singular vectors
1314* is then N1 (N or M)
1315* [[The optimal ratio N/NR for using LQ instead of padding
1316* with zeros. Here hard coded to 2; it must be at least
1317* two due to work space constraints.]]
1318* OPTRATIO = ILAENV(6, 'ZGESVD', 'S' // 'O', NR,N,0,0)
1319* OPTRATIO = MAX( OPTRATIO, 2 )
1320 optratio = 2
1321 IF ( optratio * nr .GT. n ) THEN
1322 CALL zlacpy( 'U', nr, n, a, lda, v, ldv )
1323 IF ( nr .GT. 1 )
1324 $ CALL zlaset('L', nr-1,nr-1, czero,czero, v(2,1),
1325 $ ldv)
1326* .. the right singular vectors of R overwrite [V], the NR left
1327* singular vectors of R stored in [U](1:NR,1:NR)
1328 CALL zlaset('A', n-nr,n, czero,czero, v(nr+1,1),
1329 $ ldv)
1330 CALL zgesvd( 'S', 'O', n, n, v, ldv, s, u, ldu,
1331 $ v, ldv, cwork(n+1), lcwork-n, rwork, info )
1332 CALL zlapmt( .false., n, n, v, ldv, iwork )
1333* .. now [V] contains the adjoint of the matrix of the right
1334* singular vectors of A. The leading N left singular vectors
1335* are in [U](1:N,1:N)
1336* .. assemble the left singular vector matrix U of dimensions
1337* (M x N1), i.e. (M x N) or (M x M).
1338 IF ( ( n .LT. m ) .AND. .NOT.(wntuf)) THEN
1339 CALL zlaset('A',m-n,n,czero,czero,u(n+1,1),ldu)
1340 IF ( n .LT. n1 ) THEN
1341 CALL zlaset('A',n,n1-n,czero,czero,u(1,n+1),
1342 $ ldu)
1343 CALL zlaset( 'A',m-n,n1-n,czero,cone,
1344 $ u(n+1,n+1), ldu )
1345 END IF
1346 END IF
1347 ELSE
1348 CALL zlacpy( 'U', nr, n, a, lda, u(nr+1,1), ldu )
1349 IF ( nr .GT. 1 )
1350 $ CALL zlaset('L',nr-1,nr-1,czero,czero,u(nr+2,1),
1351 $ ldu)
1352 CALL zgelqf( nr, n, u(nr+1,1), ldu, cwork(n+1),
1353 $ cwork(n+nr+1), lcwork-n-nr, ierr )
1354 CALL zlacpy('L',nr,nr,u(nr+1,1),ldu,v,ldv)
1355 IF ( nr .GT. 1 )
1356 $ CALL zlaset('U',nr-1,nr-1,czero,czero,v(1,2),ldv)
1357 CALL zgesvd( 'S', 'O', nr, nr, v, ldv, s, u, ldu,
1358 $ v, ldv, cwork(n+nr+1), lcwork-n-nr, rwork, info )
1359 CALL zlaset('A',n-nr,nr,czero,czero,v(nr+1,1),ldv)
1360 CALL zlaset('A',nr,n-nr,czero,czero,v(1,nr+1),ldv)
1361 CALL zlaset('A',n-nr,n-nr,czero,cone,v(nr+1,nr+1),
1362 $ ldv)
1363 CALL zunmlq('R','N',n,n,nr,u(nr+1,1),ldu,
1364 $ cwork(n+1),
1365 $ v, ldv, cwork(n+nr+1),lcwork-n-nr,ierr)
1366 CALL zlapmt( .false., n, n, v, ldv, iwork )
1367* .. assemble the left singular vector matrix U of dimensions
1368* (M x NR) or (M x N) or (M x M).
1369 IF ( ( nr .LT. m ) .AND. .NOT.(wntuf)) THEN
1370 CALL zlaset('A',m-nr,nr,czero,czero,u(nr+1,1),
1371 $ ldu)
1372 IF ( nr .LT. n1 ) THEN
1373 CALL zlaset('A',nr,n1-nr,czero,czero,u(1,nr+1),
1374 $ ldu)
1375 CALL zlaset( 'A',m-nr,n1-nr,czero,cone,
1376 $ u(nr+1,nr+1), ldu )
1377 END IF
1378 END IF
1379 END IF
1380 END IF
1381* .. end of the "R**H or R" branch
1382 END IF
1383*
1384* The Q matrix from the first QRF is built into the left singular
1385* vectors matrix U.
1386*
1387 IF ( .NOT. wntuf )
1388 $ CALL zunmqr( 'L', 'N', m, n1, n, a, lda, cwork, u,
1389 $ ldu, cwork(n+1), lcwork-n, ierr )
1390 IF ( rowprm .AND. .NOT.wntuf )
1391 $ CALL zlaswp( n1, u, ldu, 1, m-1, iwork(n+1), -1 )
1392*
1393* ... end of the "full SVD" branch
1394 END IF
1395*
1396* Check whether some singular values are returned as zeros, e.g.
1397* due to underflow, and update the numerical rank.
1398 p = nr
1399 DO 4001 q = p, 1, -1
1400 IF ( s(q) .GT. zero ) GO TO 4002
1401 nr = nr - 1
1402 4001 CONTINUE
1403 4002 CONTINUE
1404*
1405* .. if numerical rank deficiency is detected, the truncated
1406* singular values are set to zero.
1407 IF ( nr .LT. n ) CALL dlaset( 'G', n-nr,1, zero,zero, s(nr+1),
1408 $ n )
1409* .. undo scaling; this may cause overflow in the largest singular
1410* values.
1411 IF ( ascaled )
1412 $ CALL dlascl( 'G',0,0, one,sqrt(dble(m)), nr,1, s, n, ierr )
1413 IF ( conda ) rwork(1) = sconda
1414 rwork(2) = p - nr
1415* .. p-NR is the number of singular values that are computed as
1416* exact zeros in ZGESVD() applied to the (possibly truncated)
1417* full row rank triangular (trapezoidal) factor of A.
1418 numrank = nr
1419*
1420 RETURN
1421*
1422* End of ZGESVDQ
1423*
1424 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine zgelqf(m, n, a, lda, tau, work, lwork, info)
ZGELQF
Definition zgelqf.f:142
subroutine zgeqp3(m, n, a, lda, jpvt, tau, work, lwork, rwork, info)
ZGEQP3
Definition zgeqp3.f:157
subroutine zgeqrf(m, n, a, lda, tau, work, lwork, info)
ZGEQRF
Definition zgeqrf.f:144
subroutine zgesvd(jobu, jobvt, m, n, a, lda, s, u, ldu, vt, ldvt, work, lwork, rwork, info)
ZGESVD computes the singular value decomposition (SVD) for GE matrices
Definition zgesvd.f:212
subroutine zgesvdq(joba, jobp, jobr, jobu, jobv, m, n, a, lda, s, u, ldu, v, ldv, numrank, iwork, liwork, cwork, lcwork, rwork, lrwork, info)
ZGESVDQ computes the singular value decomposition (SVD) with a QR-Preconditioned QR SVD Method for GE...
Definition zgesvdq.f:411
subroutine zlacpy(uplo, m, n, a, lda, b, ldb)
ZLACPY copies all or part of one two-dimensional array to another.
Definition zlacpy.f:101
subroutine zlapmt(forwrd, m, n, x, ldx, k)
ZLAPMT performs a forward or backward permutation of the columns of a matrix.
Definition zlapmt.f:102
subroutine zlascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
ZLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
Definition zlascl.f:142
subroutine dlascl(type, kl, ku, cfrom, cto, m, n, a, lda, info)
DLASCL multiplies a general rectangular matrix by a real scalar defined as cto/cfrom.
Definition dlascl.f:142
subroutine dlaset(uplo, m, n, alpha, beta, a, lda)
DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
Definition dlaset.f:108
subroutine zlaset(uplo, m, n, alpha, beta, a, lda)
ZLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
Definition zlaset.f:104
subroutine zlaswp(n, a, lda, k1, k2, ipiv, incx)
ZLASWP performs a series of row interchanges on a general rectangular matrix.
Definition zlaswp.f:113
subroutine zpocon(uplo, n, a, lda, anorm, rcond, work, rwork, info)
ZPOCON
Definition zpocon.f:119
subroutine zdscal(n, da, zx, incx)
ZDSCAL
Definition zdscal.f:78
subroutine zunmlq(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
ZUNMLQ
Definition zunmlq.f:165
subroutine zunmqr(side, trans, m, n, k, a, lda, tau, c, ldc, work, lwork, info)
ZUNMQR
Definition zunmqr.f:165