LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
zggsvp3.f
Go to the documentation of this file.
1*> \brief \b ZGGSVP3
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download ZGGSVP3 + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/zggsvp3.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/zggsvp3.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/zggsvp3.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE ZGGSVP3( JOBU, JOBV, JOBQ, M, P, N, A, LDA, B, LDB,
20* TOLA, TOLB, K, L, U, LDU, V, LDV, Q, LDQ,
21* IWORK, RWORK, TAU, WORK, LWORK, INFO )
22*
23* .. Scalar Arguments ..
24* CHARACTER JOBQ, JOBU, JOBV
25* INTEGER INFO, K, L, LDA, LDB, LDQ, LDU, LDV, M, N, P, LWORK
26* DOUBLE PRECISION TOLA, TOLB
27* ..
28* .. Array Arguments ..
29* INTEGER IWORK( * )
30* DOUBLE PRECISION RWORK( * )
31* COMPLEX*16 A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
32* $ TAU( * ), U( LDU, * ), V( LDV, * ), WORK( * )
33* ..
34*
35*
36*> \par Purpose:
37* =============
38*>
39*> \verbatim
40*>
41*> ZGGSVP3 computes unitary matrices U, V and Q such that
42*>
43*> N-K-L K L
44*> U**H*A*Q = K ( 0 A12 A13 ) if M-K-L >= 0;
45*> L ( 0 0 A23 )
46*> M-K-L ( 0 0 0 )
47*>
48*> N-K-L K L
49*> = K ( 0 A12 A13 ) if M-K-L < 0;
50*> M-K ( 0 0 A23 )
51*>
52*> N-K-L K L
53*> V**H*B*Q = L ( 0 0 B13 )
54*> P-L ( 0 0 0 )
55*>
56*> where the K-by-K matrix A12 and L-by-L matrix B13 are nonsingular
57*> upper triangular; A23 is L-by-L upper triangular if M-K-L >= 0,
58*> otherwise A23 is (M-K)-by-L upper trapezoidal. K+L = the effective
59*> numerical rank of the (M+P)-by-N matrix (A**H,B**H)**H.
60*>
61*> This decomposition is the preprocessing step for computing the
62*> Generalized Singular Value Decomposition (GSVD), see subroutine
63*> ZGGSVD3.
64*> \endverbatim
65*
66* Arguments:
67* ==========
68*
69*> \param[in] JOBU
70*> \verbatim
71*> JOBU is CHARACTER*1
72*> = 'U': Unitary matrix U is computed;
73*> = 'N': U is not computed.
74*> \endverbatim
75*>
76*> \param[in] JOBV
77*> \verbatim
78*> JOBV is CHARACTER*1
79*> = 'V': Unitary matrix V is computed;
80*> = 'N': V is not computed.
81*> \endverbatim
82*>
83*> \param[in] JOBQ
84*> \verbatim
85*> JOBQ is CHARACTER*1
86*> = 'Q': Unitary matrix Q is computed;
87*> = 'N': Q is not computed.
88*> \endverbatim
89*>
90*> \param[in] M
91*> \verbatim
92*> M is INTEGER
93*> The number of rows of the matrix A. M >= 0.
94*> \endverbatim
95*>
96*> \param[in] P
97*> \verbatim
98*> P is INTEGER
99*> The number of rows of the matrix B. P >= 0.
100*> \endverbatim
101*>
102*> \param[in] N
103*> \verbatim
104*> N is INTEGER
105*> The number of columns of the matrices A and B. N >= 0.
106*> \endverbatim
107*>
108*> \param[in,out] A
109*> \verbatim
110*> A is COMPLEX*16 array, dimension (LDA,N)
111*> On entry, the M-by-N matrix A.
112*> On exit, A contains the triangular (or trapezoidal) matrix
113*> described in the Purpose section.
114*> \endverbatim
115*>
116*> \param[in] LDA
117*> \verbatim
118*> LDA is INTEGER
119*> The leading dimension of the array A. LDA >= max(1,M).
120*> \endverbatim
121*>
122*> \param[in,out] B
123*> \verbatim
124*> B is COMPLEX*16 array, dimension (LDB,N)
125*> On entry, the P-by-N matrix B.
126*> On exit, B contains the triangular matrix described in
127*> the Purpose section.
128*> \endverbatim
129*>
130*> \param[in] LDB
131*> \verbatim
132*> LDB is INTEGER
133*> The leading dimension of the array B. LDB >= max(1,P).
134*> \endverbatim
135*>
136*> \param[in] TOLA
137*> \verbatim
138*> TOLA is DOUBLE PRECISION
139*> \endverbatim
140*>
141*> \param[in] TOLB
142*> \verbatim
143*> TOLB is DOUBLE PRECISION
144*>
145*> TOLA and TOLB are the thresholds to determine the effective
146*> numerical rank of matrix B and a subblock of A. Generally,
147*> they are set to
148*> TOLA = MAX(M,N)*norm(A)*MAZHEPS,
149*> TOLB = MAX(P,N)*norm(B)*MAZHEPS.
150*> The size of TOLA and TOLB may affect the size of backward
151*> errors of the decomposition.
152*> \endverbatim
153*>
154*> \param[out] K
155*> \verbatim
156*> K is INTEGER
157*> \endverbatim
158*>
159*> \param[out] L
160*> \verbatim
161*> L is INTEGER
162*>
163*> On exit, K and L specify the dimension of the subblocks
164*> described in Purpose section.
165*> K + L = effective numerical rank of (A**H,B**H)**H.
166*> \endverbatim
167*>
168*> \param[out] U
169*> \verbatim
170*> U is COMPLEX*16 array, dimension (LDU,M)
171*> If JOBU = 'U', U contains the unitary matrix U.
172*> If JOBU = 'N', U is not referenced.
173*> \endverbatim
174*>
175*> \param[in] LDU
176*> \verbatim
177*> LDU is INTEGER
178*> The leading dimension of the array U. LDU >= max(1,M) if
179*> JOBU = 'U'; LDU >= 1 otherwise.
180*> \endverbatim
181*>
182*> \param[out] V
183*> \verbatim
184*> V is COMPLEX*16 array, dimension (LDV,P)
185*> If JOBV = 'V', V contains the unitary matrix V.
186*> If JOBV = 'N', V is not referenced.
187*> \endverbatim
188*>
189*> \param[in] LDV
190*> \verbatim
191*> LDV is INTEGER
192*> The leading dimension of the array V. LDV >= max(1,P) if
193*> JOBV = 'V'; LDV >= 1 otherwise.
194*> \endverbatim
195*>
196*> \param[out] Q
197*> \verbatim
198*> Q is COMPLEX*16 array, dimension (LDQ,N)
199*> If JOBQ = 'Q', Q contains the unitary matrix Q.
200*> If JOBQ = 'N', Q is not referenced.
201*> \endverbatim
202*>
203*> \param[in] LDQ
204*> \verbatim
205*> LDQ is INTEGER
206*> The leading dimension of the array Q. LDQ >= max(1,N) if
207*> JOBQ = 'Q'; LDQ >= 1 otherwise.
208*> \endverbatim
209*>
210*> \param[out] IWORK
211*> \verbatim
212*> IWORK is INTEGER array, dimension (N)
213*> \endverbatim
214*>
215*> \param[out] RWORK
216*> \verbatim
217*> RWORK is DOUBLE PRECISION array, dimension (2*N)
218*> \endverbatim
219*>
220*> \param[out] TAU
221*> \verbatim
222*> TAU is COMPLEX*16 array, dimension (N)
223*> \endverbatim
224*>
225*> \param[out] WORK
226*> \verbatim
227*> WORK is COMPLEX*16 array, dimension (MAX(1,LWORK))
228*> On exit, if INFO = 0, WORK(1) returns the optimal LWORK.
229*> \endverbatim
230*>
231*> \param[in] LWORK
232*> \verbatim
233*> LWORK is INTEGER
234*> The dimension of the array WORK. LWORK >= 1.
235*>
236*> If LWORK = -1, then a workspace query is assumed; the routine
237*> only calculates the optimal size of the WORK array, returns
238*> this value as the first entry of the WORK array, and no error
239*> message related to LWORK is issued by XERBLA.
240*> \endverbatim
241*>
242*> \param[out] INFO
243*> \verbatim
244*> INFO is INTEGER
245*> = 0: successful exit
246*> < 0: if INFO = -i, the i-th argument had an illegal value.
247*> \endverbatim
248*
249* Authors:
250* ========
251*
252*> \author Univ. of Tennessee
253*> \author Univ. of California Berkeley
254*> \author Univ. of Colorado Denver
255*> \author NAG Ltd.
256*
257*> \ingroup ggsvp3
258*
259*> \par Further Details:
260* =====================
261*
262*> \verbatim
263*>
264*> The subroutine uses LAPACK subroutine ZGEQP3 for the QR factorization
265*> with column pivoting to detect the effective numerical rank of the
266*> a matrix. It may be replaced by a better rank determination strategy.
267*>
268*> ZGGSVP3 replaces the deprecated subroutine ZGGSVP.
269*>
270*> \endverbatim
271*>
272* =====================================================================
273 SUBROUTINE zggsvp3( JOBU, JOBV, JOBQ, M, P, N, A, LDA, B, LDB,
274 $ TOLA, TOLB, K, L, U, LDU, V, LDV, Q, LDQ,
275 $ IWORK, RWORK, TAU, WORK, LWORK, INFO )
276*
277* -- LAPACK computational routine --
278* -- LAPACK is a software package provided by Univ. of Tennessee, --
279* -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
280*
281 IMPLICIT NONE
282*
283* .. Scalar Arguments ..
284 CHARACTER JOBQ, JOBU, JOBV
285 INTEGER INFO, K, L, LDA, LDB, LDQ, LDU, LDV, M, N, P,
286 $ lwork
287 DOUBLE PRECISION TOLA, TOLB
288* ..
289* .. Array Arguments ..
290 INTEGER IWORK( * )
291 DOUBLE PRECISION RWORK( * )
292 COMPLEX*16 A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
293 $ tau( * ), u( ldu, * ), v( ldv, * ), work( * )
294* ..
295*
296* =====================================================================
297*
298* .. Parameters ..
299 COMPLEX*16 CZERO, CONE
300 PARAMETER ( CZERO = ( 0.0d+0, 0.0d+0 ),
301 $ cone = ( 1.0d+0, 0.0d+0 ) )
302* ..
303* .. Local Scalars ..
304 LOGICAL FORWRD, WANTQ, WANTU, WANTV, LQUERY
305 INTEGER I, J, LWKOPT
306* ..
307* .. External Functions ..
308 LOGICAL LSAME
309 EXTERNAL LSAME
310* ..
311* .. External Subroutines ..
312 EXTERNAL xerbla, zgeqp3, zgeqr2, zgerq2, zlacpy,
313 $ zlapmt,
315* ..
316* .. Intrinsic Functions ..
317 INTRINSIC abs, dble, dimag, max, min
318* ..
319* .. Executable Statements ..
320*
321* Test the input parameters
322*
323 wantu = lsame( jobu, 'U' )
324 wantv = lsame( jobv, 'V' )
325 wantq = lsame( jobq, 'Q' )
326 forwrd = .true.
327 lquery = ( lwork.EQ.-1 )
328 lwkopt = 1
329*
330* Test the input arguments
331*
332 info = 0
333 IF( .NOT.( wantu .OR. lsame( jobu, 'N' ) ) ) THEN
334 info = -1
335 ELSE IF( .NOT.( wantv .OR. lsame( jobv, 'N' ) ) ) THEN
336 info = -2
337 ELSE IF( .NOT.( wantq .OR. lsame( jobq, 'N' ) ) ) THEN
338 info = -3
339 ELSE IF( m.LT.0 ) THEN
340 info = -4
341 ELSE IF( p.LT.0 ) THEN
342 info = -5
343 ELSE IF( n.LT.0 ) THEN
344 info = -6
345 ELSE IF( lda.LT.max( 1, m ) ) THEN
346 info = -8
347 ELSE IF( ldb.LT.max( 1, p ) ) THEN
348 info = -10
349 ELSE IF( ldu.LT.1 .OR. ( wantu .AND. ldu.LT.m ) ) THEN
350 info = -16
351 ELSE IF( ldv.LT.1 .OR. ( wantv .AND. ldv.LT.p ) ) THEN
352 info = -18
353 ELSE IF( ldq.LT.1 .OR. ( wantq .AND. ldq.LT.n ) ) THEN
354 info = -20
355 ELSE IF( lwork.LT.1 .AND. .NOT.lquery ) THEN
356 info = -24
357 END IF
358*
359* Compute workspace
360*
361 IF( info.EQ.0 ) THEN
362 CALL zgeqp3( p, n, b, ldb, iwork, tau, work, -1, rwork,
363 $ info )
364 lwkopt = int( work( 1 ) )
365 IF( wantv ) THEN
366 lwkopt = max( lwkopt, p )
367 END IF
368 lwkopt = max( lwkopt, min( n, p ) )
369 lwkopt = max( lwkopt, m )
370 IF( wantq ) THEN
371 lwkopt = max( lwkopt, n )
372 END IF
373 CALL zgeqp3( m, n, a, lda, iwork, tau, work, -1, rwork,
374 $ info )
375 lwkopt = max( lwkopt, int( work( 1 ) ) )
376 lwkopt = max( 1, lwkopt )
377 work( 1 ) = dcmplx( lwkopt )
378 END IF
379*
380 IF( info.NE.0 ) THEN
381 CALL xerbla( 'ZGGSVP3', -info )
382 RETURN
383 END IF
384 IF( lquery ) THEN
385 RETURN
386 ENDIF
387*
388* QR with column pivoting of B: B*P = V*( S11 S12 )
389* ( 0 0 )
390*
391 DO 10 i = 1, n
392 iwork( i ) = 0
393 10 CONTINUE
394 CALL zgeqp3( p, n, b, ldb, iwork, tau, work, lwork, rwork,
395 $ info )
396*
397* Update A := A*P
398*
399 CALL zlapmt( forwrd, m, n, a, lda, iwork )
400*
401* Determine the effective rank of matrix B.
402*
403 l = 0
404 DO 20 i = 1, min( p, n )
405 IF( abs( b( i, i ) ).GT.tolb )
406 $ l = l + 1
407 20 CONTINUE
408*
409 IF( wantv ) THEN
410*
411* Copy the details of V, and form V.
412*
413 CALL zlaset( 'Full', p, p, czero, czero, v, ldv )
414 IF( p.GT.1 )
415 $ CALL zlacpy( 'Lower', p-1, n, b( 2, 1 ), ldb, v( 2, 1 ),
416 $ ldv )
417 CALL zung2r( p, p, min( p, n ), v, ldv, tau, work, info )
418 END IF
419*
420* Clean up B
421*
422 DO 40 j = 1, l - 1
423 DO 30 i = j + 1, l
424 b( i, j ) = czero
425 30 CONTINUE
426 40 CONTINUE
427 IF( p.GT.l )
428 $ CALL zlaset( 'Full', p-l, n, czero, czero, b( l+1, 1 ),
429 $ ldb )
430*
431 IF( wantq ) THEN
432*
433* Set Q = I and Update Q := Q*P
434*
435 CALL zlaset( 'Full', n, n, czero, cone, q, ldq )
436 CALL zlapmt( forwrd, n, n, q, ldq, iwork )
437 END IF
438*
439 IF( p.GE.l .AND. n.NE.l ) THEN
440*
441* RQ factorization of ( S11 S12 ) = ( 0 S12 )*Z
442*
443 CALL zgerq2( l, n, b, ldb, tau, work, info )
444*
445* Update A := A*Z**H
446*
447 CALL zunmr2( 'Right', 'Conjugate transpose', m, n, l, b,
448 $ ldb,
449 $ tau, a, lda, work, info )
450 IF( wantq ) THEN
451*
452* Update Q := Q*Z**H
453*
454 CALL zunmr2( 'Right', 'Conjugate transpose', n, n, l, b,
455 $ ldb, tau, q, ldq, work, info )
456 END IF
457*
458* Clean up B
459*
460 CALL zlaset( 'Full', l, n-l, czero, czero, b, ldb )
461 DO 60 j = n - l + 1, n
462 DO 50 i = j - n + l + 1, l
463 b( i, j ) = czero
464 50 CONTINUE
465 60 CONTINUE
466*
467 END IF
468*
469* Let N-L L
470* A = ( A11 A12 ) M,
471*
472* then the following does the complete QR decomposition of A11:
473*
474* A11 = U*( 0 T12 )*P1**H
475* ( 0 0 )
476*
477 DO 70 i = 1, n - l
478 iwork( i ) = 0
479 70 CONTINUE
480 CALL zgeqp3( m, n-l, a, lda, iwork, tau, work, lwork, rwork,
481 $ info )
482*
483* Determine the effective rank of A11
484*
485 k = 0
486 DO 80 i = 1, min( m, n-l )
487 IF( abs( a( i, i ) ).GT.tola )
488 $ k = k + 1
489 80 CONTINUE
490*
491* Update A12 := U**H*A12, where A12 = A( 1:M, N-L+1:N )
492*
493 CALL zunm2r( 'Left', 'Conjugate transpose', m, l, min( m,
494 $ n-l ),
495 $ a, lda, tau, a( 1, n-l+1 ), lda, work, info )
496*
497 IF( wantu ) THEN
498*
499* Copy the details of U, and form U
500*
501 CALL zlaset( 'Full', m, m, czero, czero, u, ldu )
502 IF( m.GT.1 )
503 $ CALL zlacpy( 'Lower', m-1, n-l, a( 2, 1 ), lda, u( 2,
504 $ 1 ),
505 $ ldu )
506 CALL zung2r( m, m, min( m, n-l ), u, ldu, tau, work, info )
507 END IF
508*
509 IF( wantq ) THEN
510*
511* Update Q( 1:N, 1:N-L ) = Q( 1:N, 1:N-L )*P1
512*
513 CALL zlapmt( forwrd, n, n-l, q, ldq, iwork )
514 END IF
515*
516* Clean up A: set the strictly lower triangular part of
517* A(1:K, 1:K) = 0, and A( K+1:M, 1:N-L ) = 0.
518*
519 DO 100 j = 1, k - 1
520 DO 90 i = j + 1, k
521 a( i, j ) = czero
522 90 CONTINUE
523 100 CONTINUE
524 IF( m.GT.k )
525 $ CALL zlaset( 'Full', m-k, n-l, czero, czero, a( k+1, 1 ),
526 $ lda )
527*
528 IF( n-l.GT.k ) THEN
529*
530* RQ factorization of ( T11 T12 ) = ( 0 T12 )*Z1
531*
532 CALL zgerq2( k, n-l, a, lda, tau, work, info )
533*
534 IF( wantq ) THEN
535*
536* Update Q( 1:N,1:N-L ) = Q( 1:N,1:N-L )*Z1**H
537*
538 CALL zunmr2( 'Right', 'Conjugate transpose', n, n-l, k,
539 $ a,
540 $ lda, tau, q, ldq, work, info )
541 END IF
542*
543* Clean up A
544*
545 CALL zlaset( 'Full', k, n-l-k, czero, czero, a, lda )
546 DO 120 j = n - l - k + 1, n - l
547 DO 110 i = j - n + l + k + 1, k
548 a( i, j ) = czero
549 110 CONTINUE
550 120 CONTINUE
551*
552 END IF
553*
554 IF( m.GT.k ) THEN
555*
556* QR factorization of A( K+1:M,N-L+1:N )
557*
558 CALL zgeqr2( m-k, l, a( k+1, n-l+1 ), lda, tau, work, info )
559*
560 IF( wantu ) THEN
561*
562* Update U(:,K+1:M) := U(:,K+1:M)*U1
563*
564 CALL zunm2r( 'Right', 'No transpose', m, m-k, min( m-k,
565 $ l ),
566 $ a( k+1, n-l+1 ), lda, tau, u( 1, k+1 ), ldu,
567 $ work, info )
568 END IF
569*
570* Clean up
571*
572 DO 140 j = n - l + 1, n
573 DO 130 i = j - n + k + l + 1, m
574 a( i, j ) = czero
575 130 CONTINUE
576 140 CONTINUE
577*
578 END IF
579*
580 work( 1 ) = dcmplx( lwkopt )
581 RETURN
582*
583* End of ZGGSVP3
584*
585 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine zgeqp3(m, n, a, lda, jpvt, tau, work, lwork, rwork, info)
ZGEQP3
Definition zgeqp3.f:157
subroutine zgeqr2(m, n, a, lda, tau, work, info)
ZGEQR2 computes the QR factorization of a general rectangular matrix using an unblocked algorithm.
Definition zgeqr2.f:128
subroutine zgerq2(m, n, a, lda, tau, work, info)
ZGERQ2 computes the RQ factorization of a general rectangular matrix using an unblocked algorithm.
Definition zgerq2.f:121
subroutine zggsvp3(jobu, jobv, jobq, m, p, n, a, lda, b, ldb, tola, tolb, k, l, u, ldu, v, ldv, q, ldq, iwork, rwork, tau, work, lwork, info)
ZGGSVP3
Definition zggsvp3.f:276
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 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 zung2r(m, n, k, a, lda, tau, work, info)
ZUNG2R
Definition zung2r.f:112
subroutine zunm2r(side, trans, m, n, k, a, lda, tau, c, ldc, work, info)
ZUNM2R multiplies a general matrix by the unitary matrix from a QR factorization determined by cgeqrf...
Definition zunm2r.f:157
subroutine zunmr2(side, trans, m, n, k, a, lda, tau, c, ldc, work, info)
ZUNMR2 multiplies a general matrix by the unitary matrix from a RQ factorization determined by cgerqf...
Definition zunmr2.f:157