277 SUBROUTINE zggsvp3( JOBU, JOBV, JOBQ, M, P, N, A, LDA, B, LDB,
278 $ tola, tolb, k, l, u, ldu, v, ldv, q, ldq,
279 $ iwork, rwork, tau, work, lwork, info )
289 CHARACTER JOBQ, JOBU, JOBV
290 INTEGER INFO, K, L, LDA, LDB, LDQ, LDU, LDV, M, N, P,
292 DOUBLE PRECISION TOLA, TOLB
296 DOUBLE PRECISION RWORK( * )
297 COMPLEX*16 A( lda, * ), B( ldb, * ), Q( ldq, * ),
298 $ tau( * ), u( ldu, * ), v( ldv, * ), work( * )
304 COMPLEX*16 CZERO, CONE
305 parameter ( czero = ( 0.0d+0, 0.0d+0 ),
306 $ cone = ( 1.0d+0, 0.0d+0 ) )
309 LOGICAL FORWRD, WANTQ, WANTU, WANTV, LQUERY
321 INTRINSIC abs, dble, dimag, max, min
327 wantu = lsame( jobu,
'U' )
328 wantv = lsame( jobv,
'V' )
329 wantq = lsame( jobq,
'Q' )
331 lquery = ( lwork.EQ.-1 )
337 IF( .NOT.( wantu .OR. lsame( jobu,
'N' ) ) )
THEN
339 ELSE IF( .NOT.( wantv .OR. lsame( jobv,
'N' ) ) )
THEN
341 ELSE IF( .NOT.( wantq .OR. lsame( jobq,
'N' ) ) )
THEN
343 ELSE IF( m.LT.0 )
THEN
345 ELSE IF( p.LT.0 )
THEN
347 ELSE IF( n.LT.0 )
THEN
349 ELSE IF( lda.LT.max( 1, m ) )
THEN
351 ELSE IF( ldb.LT.max( 1, p ) )
THEN
353 ELSE IF( ldu.LT.1 .OR. ( wantu .AND. ldu.LT.m ) )
THEN
355 ELSE IF( ldv.LT.1 .OR. ( wantv .AND. ldv.LT.p ) )
THEN
357 ELSE IF( ldq.LT.1 .OR. ( wantq .AND. ldq.LT.n ) )
THEN
359 ELSE IF( lwork.LT.1 .AND. .NOT.lquery )
THEN
366 CALL zgeqp3( p, n, b, ldb, iwork, tau, work, -1, rwork, info )
367 lwkopt = int( work( 1 ) )
369 lwkopt = max( lwkopt, p )
371 lwkopt = max( lwkopt, min( n, p ) )
372 lwkopt = max( lwkopt, m )
374 lwkopt = max( lwkopt, n )
376 CALL zgeqp3( m, n, a, lda, iwork, tau, work, -1, rwork, info )
377 lwkopt = max( lwkopt, int( work( 1 ) ) )
378 lwkopt = max( 1, lwkopt )
379 work( 1 ) = dcmplx( lwkopt )
383 CALL xerbla(
'ZGGSVP3', -info )
396 CALL zgeqp3( p, n, b, ldb, iwork, tau, work, lwork, rwork, info )
400 CALL zlapmt( forwrd, m, n, a, lda, iwork )
405 DO 20 i = 1, min( p, n )
406 IF( abs( b( i, i ) ).GT.tolb )
414 CALL zlaset(
'Full', p, p, czero, czero, v, ldv )
416 $
CALL zlacpy(
'Lower', p-1, n, b( 2, 1 ), ldb, v( 2, 1 ),
418 CALL zung2r( p, p, min( p, n ), v, ldv, tau, work, info )
429 $
CALL zlaset(
'Full', p-l, n, czero, czero, b( l+1, 1 ), ldb )
435 CALL zlaset(
'Full', n, n, czero, cone, q, ldq )
436 CALL zlapmt( forwrd, n, n, q, ldq, iwork )
439 IF( p.GE.l .AND. n.NE.l )
THEN
443 CALL zgerq2( l, n, b, ldb, tau, work, info )
447 CALL zunmr2(
'Right',
'Conjugate transpose', m, n, l, b, ldb,
448 $ tau, a, lda, work, info )
453 CALL zunmr2(
'Right',
'Conjugate transpose', n, n, l, b,
454 $ ldb, tau, q, ldq, work, info )
459 CALL zlaset(
'Full', l, n-l, czero, czero, b, ldb )
460 DO 60 j = n - l + 1, n
461 DO 50 i = j - n + l + 1, l
479 CALL zgeqp3( m, n-l, a, lda, iwork, tau, work, lwork, rwork,
485 DO 80 i = 1, min( m, n-l )
486 IF( abs( a( i, i ) ).GT.tola )
492 CALL zunm2r(
'Left',
'Conjugate transpose', m, l, min( m, n-l ),
493 $ a, lda, tau, a( 1, n-l+1 ), lda, work, info )
499 CALL zlaset(
'Full', m, m, czero, czero, u, ldu )
501 $
CALL zlacpy(
'Lower', m-1, n-l, a( 2, 1 ), lda, u( 2, 1 ),
503 CALL zung2r( m, m, min( m, n-l ), u, ldu, tau, work, info )
510 CALL zlapmt( forwrd, n, n-l, q, ldq, iwork )
522 $
CALL zlaset(
'Full', m-k, n-l, czero, czero, a( k+1, 1 ), lda )
528 CALL zgerq2( k, n-l, a, lda, tau, work, info )
534 CALL zunmr2(
'Right',
'Conjugate transpose', n, n-l, k, a,
535 $ lda, tau, q, ldq, work, info )
540 CALL zlaset(
'Full', k, n-l-k, czero, czero, a, lda )
541 DO 120 j = n - l - k + 1, n - l
542 DO 110 i = j - n + l + k + 1, k
553 CALL zgeqr2( m-k, l, a( k+1, n-l+1 ), lda, tau, work, info )
559 CALL zunm2r(
'Right',
'No transpose', m, m-k, min( m-k, l ),
560 $ a( k+1, n-l+1 ), lda, tau, u( 1, k+1 ), ldu,
566 DO 140 j = n - l + 1, n
567 DO 130 i = j - n + k + l + 1, m
574 work( 1 ) = dcmplx( lwkopt )
subroutine zung2r(M, N, K, A, LDA, TAU, WORK, INFO)
ZUNG2R
subroutine zlacpy(UPLO, M, N, A, LDA, B, LDB)
ZLACPY copies all or part of one two-dimensional array to another.
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...
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...
subroutine zlapmt(FORWRD, M, N, X, LDX, K)
ZLAPMT performs a forward or backward permutation of the columns of a matrix.
subroutine xerbla(SRNAME, INFO)
XERBLA
subroutine zgeqr2(M, N, A, LDA, TAU, WORK, INFO)
ZGEQR2 computes the QR factorization of a general rectangular matrix using an unblocked algorithm...
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...
subroutine zgeqp3(M, N, A, LDA, JPVT, TAU, WORK, LWORK, RWORK, INFO)
ZGEQP3
subroutine zgerq2(M, N, A, LDA, TAU, WORK, INFO)
ZGERQ2 computes the RQ factorization of a general rectangular matrix using an unblocked algorithm...
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