LAPACK 3.12.1
LAPACK: Linear Algebra PACKage
Loading...
Searching...
No Matches
cggsvp3.f
Go to the documentation of this file.
1*> \brief \b CGGSVP3
2*
3* =========== DOCUMENTATION ===========
4*
5* Online html documentation available at
6* http://www.netlib.org/lapack/explore-html/
7*
8*> Download CGGSVP3 + dependencies
9*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/cggsvp3.f">
10*> [TGZ]</a>
11*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/cggsvp3.f">
12*> [ZIP]</a>
13*> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/cggsvp3.f">
14*> [TXT]</a>
15*
16* Definition:
17* ===========
18*
19* SUBROUTINE CGGSVP3( 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* REAL TOLA, TOLB
27* ..
28* .. Array Arguments ..
29* INTEGER IWORK( * )
30* REAL RWORK( * )
31* COMPLEX 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*> CGGSVP3 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*> CGGSVD3.
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 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 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 REAL
139*> \endverbatim
140*>
141*> \param[in] TOLB
142*> \verbatim
143*> TOLB is REAL
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)*MACHEPS,
149*> TOLB = MAX(P,N)*norm(B)*MACHEPS.
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 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 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 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 REAL array, dimension (2*N)
218*> \endverbatim
219*>
220*> \param[out] TAU
221*> \verbatim
222*> TAU is COMPLEX array, dimension (N)
223*> \endverbatim
224*>
225*> \param[out] WORK
226*> \verbatim
227*> WORK is COMPLEX 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 CGEQP3 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*> CGGSVP3 replaces the deprecated subroutine CGGSVP.
269*>
270*> \endverbatim
271*>
272* =====================================================================
273 SUBROUTINE cggsvp3( 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 REAL TOLA, TOLB
288* ..
289* .. Array Arguments ..
290 INTEGER IWORK( * )
291 REAL RWORK( * )
292 COMPLEX A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
293 $ tau( * ), u( ldu, * ), v( ldv, * ), work( * )
294* ..
295*
296* =====================================================================
297*
298* .. Parameters ..
299 COMPLEX CZERO, CONE
300 PARAMETER ( CZERO = ( 0.0e+0, 0.0e+0 ),
301 $ cone = ( 1.0e+0, 0.0e+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 cgeqp3, cgeqr2, cgerq2, clacpy,
313 $ clapmt,
315* ..
316* .. Intrinsic Functions ..
317 INTRINSIC abs, aimag, max, min, real
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 cgeqp3( 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 cgeqp3( 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 ) = cmplx( lwkopt )
378 END IF
379*
380 IF( info.NE.0 ) THEN
381 CALL xerbla( 'CGGSVP3', -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 cgeqp3( p, n, b, ldb, iwork, tau, work, lwork, rwork,
395 $ info )
396*
397* Update A := A*P
398*
399 CALL clapmt( 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 claset( 'Full', p, p, czero, czero, v, ldv )
414 IF( p.GT.1 )
415 $ CALL clacpy( 'Lower', p-1, n, b( 2, 1 ), ldb, v( 2, 1 ),
416 $ ldv )
417 CALL cung2r( 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 claset( '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 claset( 'Full', n, n, czero, cone, q, ldq )
436 CALL clapmt( 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 cgerq2( l, n, b, ldb, tau, work, info )
444*
445* Update A := A*Z**H
446*
447 CALL cunmr2( '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 cunmr2( '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 claset( '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 cgeqp3( 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 cunm2r( '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 claset( 'Full', m, m, czero, czero, u, ldu )
502 IF( m.GT.1 )
503 $ CALL clacpy( 'Lower', m-1, n-l, a( 2, 1 ), lda, u( 2,
504 $ 1 ),
505 $ ldu )
506 CALL cung2r( 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 clapmt( 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 claset( '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 cgerq2( 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 cunmr2( '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 claset( '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 cgeqr2( 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 cunm2r( '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 ) = cmplx( lwkopt )
581 RETURN
582*
583* End of CGGSVP3
584*
585 END
subroutine xerbla(srname, info)
Definition cblat2.f:3285
subroutine cgeqp3(m, n, a, lda, jpvt, tau, work, lwork, rwork, info)
CGEQP3
Definition cgeqp3.f:157
subroutine cgeqr2(m, n, a, lda, tau, work, info)
CGEQR2 computes the QR factorization of a general rectangular matrix using an unblocked algorithm.
Definition cgeqr2.f:128
subroutine cgerq2(m, n, a, lda, tau, work, info)
CGERQ2 computes the RQ factorization of a general rectangular matrix using an unblocked algorithm.
Definition cgerq2.f:121
subroutine cggsvp3(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)
CGGSVP3
Definition cggsvp3.f:276
subroutine clacpy(uplo, m, n, a, lda, b, ldb)
CLACPY copies all or part of one two-dimensional array to another.
Definition clacpy.f:101
subroutine clapmt(forwrd, m, n, x, ldx, k)
CLAPMT performs a forward or backward permutation of the columns of a matrix.
Definition clapmt.f:102
subroutine claset(uplo, m, n, alpha, beta, a, lda)
CLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
Definition claset.f:104
subroutine cung2r(m, n, k, a, lda, tau, work, info)
CUNG2R
Definition cung2r.f:112
subroutine cunm2r(side, trans, m, n, k, a, lda, tau, c, ldc, work, info)
CUNM2R multiplies a general matrix by the unitary matrix from a QR factorization determined by cgeqrf...
Definition cunm2r.f:157
subroutine cunmr2(side, trans, m, n, k, a, lda, tau, c, ldc, work, info)
CUNMR2 multiplies a general matrix by the unitary matrix from a RQ factorization determined by cgerqf...
Definition cunmr2.f:157