3 * =========== DOCUMENTATION ===========
5 * Online html documentation available at
6 * http://www.netlib.org/lapack/explore-html/
9 *> Download CTGSJA + dependencies
10 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.tgz?format=tgz&filename=/lapack/lapack_routine/ctgsja.f">
12 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.zip?format=zip&filename=/lapack/lapack_routine/ctgsja.f">
14 *> <a href="http://www.netlib.org/cgi-bin/netlibfiles.txt?format=txt&filename=/lapack/lapack_routine/ctgsja.f">
21 * SUBROUTINE CTGSJA( JOBU, JOBV, JOBQ, M, P, N, K, L, A, LDA, B,
22 * LDB, TOLA, TOLB, ALPHA, BETA, U, LDU, V, LDV,
23 * Q, LDQ, WORK, NCYCLE, INFO )
25 * .. Scalar Arguments ..
26 * CHARACTER JOBQ, JOBU, JOBV
27 * INTEGER INFO, K, L, LDA, LDB, LDQ, LDU, LDV, M, N,
31 * .. Array Arguments ..
32 * REAL ALPHA( * ), BETA( * )
33 * COMPLEX A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
34 * $ U( LDU, * ), V( LDV, * ), WORK( * )
43 *> CTGSJA computes the generalized singular value decomposition (GSVD)
44 *> of two complex upper triangular (or trapezoidal) matrices A and B.
46 *> On entry, it is assumed that matrices A and B have the following
47 *> forms, which may be obtained by the preprocessing subroutine CGGSVP
48 *> from a general M-by-N matrix A and P-by-N matrix B:
51 *> A = K ( 0 A12 A13 ) if M-K-L >= 0;
56 *> A = K ( 0 A12 A13 ) if M-K-L < 0;
63 *> where the K-by-K matrix A12 and L-by-L matrix B13 are nonsingular
64 *> upper triangular; A23 is L-by-L upper triangular if M-K-L >= 0,
65 *> otherwise A23 is (M-K)-by-L upper trapezoidal.
69 *> U**H *A*Q = D1*( 0 R ), V**H *B*Q = D2*( 0 R ),
71 *> where U, V and Q are unitary matrices.
72 *> R is a nonsingular upper triangular matrix, and D1
73 *> and D2 are ``diagonal'' matrices, which are of the following
88 *> ( 0 R ) = K ( 0 R11 R12 ) K
93 *> C = diag( ALPHA(K+1), ... , ALPHA(K+L) ),
94 *> S = diag( BETA(K+1), ... , BETA(K+L) ),
97 *> R is stored in A(1:K+L,N-K-L+1:N) on exit.
106 *> D2 = M-K ( 0 S 0 )
111 *> ( 0 R ) = K ( 0 R11 R12 R13 )
112 *> M-K ( 0 0 R22 R23 )
113 *> K+L-M ( 0 0 0 R33 )
116 *> C = diag( ALPHA(K+1), ... , ALPHA(M) ),
117 *> S = diag( BETA(K+1), ... , BETA(M) ),
120 *> R = ( R11 R12 R13 ) is stored in A(1:M, N-K-L+1:N) and R33 is stored
122 *> in B(M-K+1:L,N+M-K-L+1:N) on exit.
124 *> The computation of the unitary transformation matrices U, V or Q
125 *> is optional. These matrices may either be formed explicitly, or they
126 *> may be postmultiplied into input matrices U1, V1, or Q1.
134 *> JOBU is CHARACTER*1
135 *> = 'U': U must contain a unitary matrix U1 on entry, and
136 *> the product U1*U is returned;
137 *> = 'I': U is initialized to the unit matrix, and the
138 *> unitary matrix U is returned;
139 *> = 'N': U is not computed.
144 *> JOBV is CHARACTER*1
145 *> = 'V': V must contain a unitary matrix V1 on entry, and
146 *> the product V1*V is returned;
147 *> = 'I': V is initialized to the unit matrix, and the
148 *> unitary matrix V is returned;
149 *> = 'N': V is not computed.
154 *> JOBQ is CHARACTER*1
155 *> = 'Q': Q must contain a unitary matrix Q1 on entry, and
156 *> the product Q1*Q is returned;
157 *> = 'I': Q is initialized to the unit matrix, and the
158 *> unitary matrix Q is returned;
159 *> = 'N': Q is not computed.
165 *> The number of rows of the matrix A. M >= 0.
171 *> The number of rows of the matrix B. P >= 0.
177 *> The number of columns of the matrices A and B. N >= 0.
189 *> K and L specify the subblocks in the input matrices A and B:
190 *> A23 = A(K+1:MIN(K+L,M),N-L+1:N) and B13 = B(1:L,,N-L+1:N)
191 *> of A and B, whose GSVD is going to be computed by CTGSJA.
192 *> See Further Details.
197 *> A is COMPLEX array, dimension (LDA,N)
198 *> On entry, the M-by-N matrix A.
199 *> On exit, A(N-K+1:N,1:MIN(K+L,M) ) contains the triangular
200 *> matrix R or part of R. See Purpose for details.
206 *> The leading dimension of the array A. LDA >= max(1,M).
211 *> B is COMPLEX array, dimension (LDB,N)
212 *> On entry, the P-by-N matrix B.
213 *> On exit, if necessary, B(M-K+1:L,N+M-K-L+1:N) contains
214 *> a part of R. See Purpose for details.
220 *> The leading dimension of the array B. LDB >= max(1,P).
232 *> TOLA and TOLB are the convergence criteria for the Jacobi-
233 *> Kogbetliantz iteration procedure. Generally, they are the
234 *> same as used in the preprocessing step, say
235 *> TOLA = MAX(M,N)*norm(A)*MACHEPS,
236 *> TOLB = MAX(P,N)*norm(B)*MACHEPS.
241 *> ALPHA is REAL array, dimension (N)
246 *> BETA is REAL array, dimension (N)
248 *> On exit, ALPHA and BETA contain the generalized singular
249 *> value pairs of A and B;
252 *> and if M-K-L >= 0,
253 *> ALPHA(K+1:K+L) = diag(C),
254 *> BETA(K+1:K+L) = diag(S),
256 *> ALPHA(K+1:M)= C, ALPHA(M+1:K+L)= 0
257 *> BETA(K+1:M) = S, BETA(M+1:K+L) = 1.
258 *> Furthermore, if K+L < N,
259 *> ALPHA(K+L+1:N) = 0
260 *> BETA(K+L+1:N) = 0.
265 *> U is COMPLEX array, dimension (LDU,M)
266 *> On entry, if JOBU = 'U', U must contain a matrix U1 (usually
267 *> the unitary matrix returned by CGGSVP).
269 *> if JOBU = 'I', U contains the unitary matrix U;
270 *> if JOBU = 'U', U contains the product U1*U.
271 *> If JOBU = 'N', U is not referenced.
277 *> The leading dimension of the array U. LDU >= max(1,M) if
278 *> JOBU = 'U'; LDU >= 1 otherwise.
283 *> V is COMPLEX array, dimension (LDV,P)
284 *> On entry, if JOBV = 'V', V must contain a matrix V1 (usually
285 *> the unitary matrix returned by CGGSVP).
287 *> if JOBV = 'I', V contains the unitary matrix V;
288 *> if JOBV = 'V', V contains the product V1*V.
289 *> If JOBV = 'N', V is not referenced.
295 *> The leading dimension of the array V. LDV >= max(1,P) if
296 *> JOBV = 'V'; LDV >= 1 otherwise.
301 *> Q is COMPLEX array, dimension (LDQ,N)
302 *> On entry, if JOBQ = 'Q', Q must contain a matrix Q1 (usually
303 *> the unitary matrix returned by CGGSVP).
305 *> if JOBQ = 'I', Q contains the unitary matrix Q;
306 *> if JOBQ = 'Q', Q contains the product Q1*Q.
307 *> If JOBQ = 'N', Q is not referenced.
313 *> The leading dimension of the array Q. LDQ >= max(1,N) if
314 *> JOBQ = 'Q'; LDQ >= 1 otherwise.
319 *> WORK is COMPLEX array, dimension (2*N)
322 *> \param[out] NCYCLE
325 *> The number of cycles required for convergence.
331 *> = 0: successful exit
332 *> < 0: if INFO = -i, the i-th argument had an illegal value.
333 *> = 1: the procedure does not converge after MAXIT cycles.
336 *> \par Internal Parameters:
337 * =========================
341 *> MAXIT specifies the total loops that the iterative procedure
342 *> may take. If after MAXIT cycles, the routine fails to
343 *> converge, we return INFO = 1.
349 *> \author Univ. of Tennessee
350 *> \author Univ. of California Berkeley
351 *> \author Univ. of Colorado Denver
354 *> \date November 2011
356 *> \ingroup complexOTHERcomputational
358 *> \par Further Details:
359 * =====================
363 *> CTGSJA essentially uses a variant of Kogbetliantz algorithm to reduce
364 *> min(L,M-K)-by-L triangular (or trapezoidal) matrix A23 and L-by-L
365 *> matrix B13 to the form:
367 *> U1**H *A13*Q1 = C1*R1; V1**H *B13*Q1 = S1*R1,
369 *> where U1, V1 and Q1 are unitary matrix.
370 *> C1 and S1 are diagonal matrices satisfying
372 *> C1**2 + S1**2 = I,
374 *> and R1 is an L-by-L nonsingular upper triangular matrix.
377 * =====================================================================
378 SUBROUTINE CTGSJA( JOBU, JOBV, JOBQ, M, P, N, K, L, A, LDA, B,
379 $ LDB, TOLA, TOLB, ALPHA, BETA, U, LDU, V, LDV,
380 $ Q, LDQ, WORK, NCYCLE, INFO )
382 * -- LAPACK computational routine (version 3.4.0) --
383 * -- LAPACK is a software package provided by Univ. of Tennessee, --
384 * -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
387 * .. Scalar Arguments ..
388 CHARACTER JOBQ, JOBU, JOBV
389 INTEGER INFO, K, L, LDA, LDB, LDQ, LDU, LDV, M, N,
393 * .. Array Arguments ..
394 REAL ALPHA( * ), BETA( * )
395 COMPLEX A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
396 $ U( LDU, * ), V( LDV, * ), WORK( * )
399 * =====================================================================
403 PARAMETER ( MAXIT = 40 )
405 PARAMETER ( ZERO = 0.0E+0, ONE = 1.0E+0 )
407 PARAMETER ( CZERO = ( 0.0E+0, 0.0E+0 ),
408 $ CONE = ( 1.0E+0, 0.0E+0 ) )
410 * .. Local Scalars ..
412 LOGICAL INITQ, INITU, INITV, UPPER, WANTQ, WANTU, WANTV
414 REAL A1, A3, B1, B3, CSQ, CSU, CSV, ERROR, GAMMA,
416 COMPLEX A2, B2, SNQ, SNU, SNV
418 * .. External Functions ..
422 * .. External Subroutines ..
423 EXTERNAL CCOPY, CLAGS2, CLAPLL, CLASET, CROT, CSSCAL,
426 * .. Intrinsic Functions ..
427 INTRINSIC ABS, CONJG, MAX, MIN, REAL
429 * .. Executable Statements ..
431 * Decode and test the input parameters
433 INITU = LSAME( JOBU, 'I' )
434 WANTU = INITU .OR. LSAME( JOBU, 'U' )
436 INITV = LSAME( JOBV, 'I' )
437 WANTV = INITV .OR. LSAME( JOBV, 'V' )
439 INITQ = LSAME( JOBQ, 'I' )
440 WANTQ = INITQ .OR. LSAME( JOBQ, 'Q' )
443 IF( .NOT.( INITU .OR. WANTU .OR. LSAME( JOBU, 'N' ) ) ) THEN
445 ELSE IF( .NOT.( INITV .OR. WANTV .OR. LSAME( JOBV, 'N' ) ) ) THEN
447 ELSE IF( .NOT.( INITQ .OR. WANTQ .OR. LSAME( JOBQ, 'N' ) ) ) THEN
449 ELSE IF( M.LT.0 ) THEN
451 ELSE IF( P.LT.0 ) THEN
453 ELSE IF( N.LT.0 ) THEN
455 ELSE IF( LDA.LT.MAX( 1, M ) ) THEN
457 ELSE IF( LDB.LT.MAX( 1, P ) ) THEN
459 ELSE IF( LDU.LT.1 .OR. ( WANTU .AND. LDU.LT.M ) ) THEN
461 ELSE IF( LDV.LT.1 .OR. ( WANTV .AND. LDV.LT.P ) ) THEN
463 ELSE IF( LDQ.LT.1 .OR. ( WANTQ .AND. LDQ.LT.N ) ) THEN
467 CALL XERBLA( 'CTGSJA', -INFO )
471 * Initialize U, V and Q, if necessary
474 $ CALL CLASET( 'Full', M, M, CZERO, CONE, U, LDU )
476 $ CALL CLASET( 'Full', P, P, CZERO, CONE, V, LDV )
478 $ CALL CLASET( 'Full', N, N, CZERO, CONE, Q, LDQ )
480 * Loop until convergence
483 DO 40 KCYCLE = 1, MAXIT
494 $ A1 = REAL( A( K+I, N-L+I ) )
496 $ A3 = REAL( A( K+J, N-L+J ) )
498 B1 = REAL( B( I, N-L+I ) )
499 B3 = REAL( B( J, N-L+J ) )
503 $ A2 = A( K+I, N-L+J )
507 $ A2 = A( K+J, N-L+I )
511 CALL CLAGS2( UPPER, A1, A2, A3, B1, B2, B3, CSU, SNU,
512 $ CSV, SNV, CSQ, SNQ )
514 * Update (K+I)-th and (K+J)-th rows of matrix A: U**H *A
517 $ CALL CROT( L, A( K+J, N-L+1 ), LDA, A( K+I, N-L+1 ),
518 $ LDA, CSU, CONJG( SNU ) )
520 * Update I-th and J-th rows of matrix B: V**H *B
522 CALL CROT( L, B( J, N-L+1 ), LDB, B( I, N-L+1 ), LDB,
523 $ CSV, CONJG( SNV ) )
525 * Update (N-L+I)-th and (N-L+J)-th columns of matrices
526 * A and B: A*Q and B*Q
528 CALL CROT( MIN( K+L, M ), A( 1, N-L+J ), 1,
529 $ A( 1, N-L+I ), 1, CSQ, SNQ )
531 CALL CROT( L, B( 1, N-L+J ), 1, B( 1, N-L+I ), 1, CSQ,
536 $ A( K+I, N-L+J ) = CZERO
537 B( I, N-L+J ) = CZERO
540 $ A( K+J, N-L+I ) = CZERO
541 B( J, N-L+I ) = CZERO
544 * Ensure that the diagonal elements of A and B are real.
547 $ A( K+I, N-L+I ) = REAL( A( K+I, N-L+I ) )
549 $ A( K+J, N-L+J ) = REAL( A( K+J, N-L+J ) )
550 B( I, N-L+I ) = REAL( B( I, N-L+I ) )
551 B( J, N-L+J ) = REAL( B( J, N-L+J ) )
553 * Update unitary matrices U, V, Q, if desired.
555 IF( WANTU .AND. K+J.LE.M )
556 $ CALL CROT( M, U( 1, K+J ), 1, U( 1, K+I ), 1, CSU,
560 $ CALL CROT( P, V( 1, J ), 1, V( 1, I ), 1, CSV, SNV )
563 $ CALL CROT( N, Q( 1, N-L+J ), 1, Q( 1, N-L+I ), 1, CSQ,
569 IF( .NOT.UPPER ) THEN
571 * The matrices A13 and B13 were lower triangular at the start
572 * of the cycle, and are now upper triangular.
574 * Convergence test: test the parallelism of the corresponding
578 DO 30 I = 1, MIN( L, M-K )
579 CALL CCOPY( L-I+1, A( K+I, N-L+I ), LDA, WORK, 1 )
580 CALL CCOPY( L-I+1, B( I, N-L+I ), LDB, WORK( L+1 ), 1 )
581 CALL CLAPLL( L-I+1, WORK, 1, WORK( L+1 ), 1, SSMIN )
582 ERROR = MAX( ERROR, SSMIN )
585 IF( ABS( ERROR ).LE.MIN( TOLA, TOLB ) )
593 * The algorithm has not converged after MAXIT cycles.
600 * If ERROR <= MIN(TOLA,TOLB), then the algorithm has converged.
601 * Compute the generalized singular value pairs (ALPHA, BETA), and
602 * set the triangular matrix R to array A.
609 DO 70 I = 1, MIN( L, M-K )
611 A1 = REAL( A( K+I, N-L+I ) )
612 B1 = REAL( B( I, N-L+I ) )
614 IF( A1.NE.ZERO ) THEN
617 IF( GAMMA.LT.ZERO ) THEN
618 CALL CSSCAL( L-I+1, -ONE, B( I, N-L+I ), LDB )
620 $ CALL CSSCAL( P, -ONE, V( 1, I ), 1 )
623 CALL SLARTG( ABS( GAMMA ), ONE, BETA( K+I ), ALPHA( K+I ),
626 IF( ALPHA( K+I ).GE.BETA( K+I ) ) THEN
627 CALL CSSCAL( L-I+1, ONE / ALPHA( K+I ), A( K+I, N-L+I ),
630 CALL CSSCAL( L-I+1, ONE / BETA( K+I ), B( I, N-L+I ),
632 CALL CCOPY( L-I+1, B( I, N-L+I ), LDB, A( K+I, N-L+I ),
639 CALL CCOPY( L-I+1, B( I, N-L+I ), LDB, A( K+I, N-L+I ),
646 DO 80 I = M + 1, K + L
652 DO 90 I = K + L + 1, N