275 SUBROUTINE zggsvp3( JOBU, JOBV, JOBQ, M, P, N, A, LDA, B, LDB,
276 $ TOLA, TOLB, K, L, U, LDU, V, LDV, Q, LDQ,
277 $ IWORK, RWORK, TAU, WORK, LWORK, INFO )
286 CHARACTER JOBQ, JOBU, JOBV
287 INTEGER INFO, K, L, LDA, LDB, LDQ, LDU, LDV, M, N, P,
289 DOUBLE PRECISION TOLA, TOLB
293 DOUBLE PRECISION RWORK( * )
294 COMPLEX*16 A( lda, * ), B( ldb, * ), Q( ldq, * ),
295 $ tau( * ), u( ldu, * ), v( ldv, * ), work( * )
301 COMPLEX*16 CZERO, CONE
302 parameter( czero = ( 0.0d+0, 0.0d+0 ),
303 $ cone = ( 1.0d+0, 0.0d+0 ) )
306 LOGICAL FORWRD, WANTQ, WANTU, WANTV, LQUERY
318 INTRINSIC abs, dble, dimag, max, min
324 wantu = lsame( jobu,
'U' )
325 wantv = lsame( jobv,
'V' )
326 wantq = lsame( jobq,
'Q' )
328 lquery = ( lwork.EQ.-1 )
334 IF( .NOT.( wantu .OR. lsame( jobu,
'N' ) ) )
THEN 336 ELSE IF( .NOT.( wantv .OR. lsame( jobv,
'N' ) ) )
THEN 338 ELSE IF( .NOT.( wantq .OR. lsame( jobq,
'N' ) ) )
THEN 340 ELSE IF( m.LT.0 )
THEN 342 ELSE IF( p.LT.0 )
THEN 344 ELSE IF( n.LT.0 )
THEN 346 ELSE IF( lda.LT.max( 1, m ) )
THEN 348 ELSE IF( ldb.LT.max( 1, p ) )
THEN 350 ELSE IF( ldu.LT.1 .OR. ( wantu .AND. ldu.LT.m ) )
THEN 352 ELSE IF( ldv.LT.1 .OR. ( wantv .AND. ldv.LT.p ) )
THEN 354 ELSE IF( ldq.LT.1 .OR. ( wantq .AND. ldq.LT.n ) )
THEN 356 ELSE IF( lwork.LT.1 .AND. .NOT.lquery )
THEN 363 CALL zgeqp3( p, n, b, ldb, iwork, tau, work, -1, rwork, info )
364 lwkopt = int( work( 1 ) )
366 lwkopt = max( lwkopt, p )
368 lwkopt = max( lwkopt, min( n, p ) )
369 lwkopt = max( lwkopt, m )
371 lwkopt = max( lwkopt, n )
373 CALL zgeqp3( m, n, a, lda, iwork, tau, work, -1, rwork, info )
374 lwkopt = max( lwkopt, int( work( 1 ) ) )
375 lwkopt = max( 1, lwkopt )
376 work( 1 ) = dcmplx( lwkopt )
380 CALL xerbla(
'ZGGSVP3', -info )
393 CALL zgeqp3( p, n, b, ldb, iwork, tau, work, lwork, rwork, info )
397 CALL zlapmt( forwrd, m, n, a, lda, iwork )
402 DO 20 i = 1, min( p, n )
403 IF( abs( b( i, i ) ).GT.tolb )
411 CALL zlaset(
'Full', p, p, czero, czero, v, ldv )
413 $
CALL zlacpy(
'Lower', p-1, n, b( 2, 1 ), ldb, v( 2, 1 ),
415 CALL zung2r( p, p, min( p, n ), v, ldv, tau, work, info )
426 $
CALL zlaset(
'Full', p-l, n, czero, czero, b( l+1, 1 ), ldb )
432 CALL zlaset(
'Full', n, n, czero, cone, q, ldq )
433 CALL zlapmt( forwrd, n, n, q, ldq, iwork )
436 IF( p.GE.l .AND. n.NE.l )
THEN 440 CALL zgerq2( l, n, b, ldb, tau, work, info )
444 CALL zunmr2(
'Right',
'Conjugate transpose', m, n, l, b, ldb,
445 $ tau, a, lda, work, info )
450 CALL zunmr2(
'Right',
'Conjugate transpose', n, n, l, b,
451 $ ldb, tau, q, ldq, work, info )
456 CALL zlaset(
'Full', l, n-l, czero, czero, b, ldb )
457 DO 60 j = n - l + 1, n
458 DO 50 i = j - n + l + 1, l
476 CALL zgeqp3( m, n-l, a, lda, iwork, tau, work, lwork, rwork,
482 DO 80 i = 1, min( m, n-l )
483 IF( abs( a( i, i ) ).GT.tola )
489 CALL zunm2r(
'Left',
'Conjugate transpose', m, l, min( m, n-l ),
490 $ a, lda, tau, a( 1, n-l+1 ), lda, work, info )
496 CALL zlaset(
'Full', m, m, czero, czero, u, ldu )
498 $
CALL zlacpy(
'Lower', m-1, n-l, a( 2, 1 ), lda, u( 2, 1 ),
500 CALL zung2r( m, m, min( m, n-l ), u, ldu, tau, work, info )
507 CALL zlapmt( forwrd, n, n-l, q, ldq, iwork )
519 $
CALL zlaset(
'Full', m-k, n-l, czero, czero, a( k+1, 1 ), lda )
525 CALL zgerq2( k, n-l, a, lda, tau, work, info )
531 CALL zunmr2(
'Right',
'Conjugate transpose', n, n-l, k, a,
532 $ lda, tau, q, ldq, work, info )
537 CALL zlaset(
'Full', k, n-l-k, czero, czero, a, lda )
538 DO 120 j = n - l - k + 1, n - l
539 DO 110 i = j - n + l + k + 1, k
550 CALL zgeqr2( m-k, l, a( k+1, n-l+1 ), lda, tau, work, info )
556 CALL zunm2r(
'Right',
'No transpose', m, m-k, min( m-k, l ),
557 $ a( k+1, n-l+1 ), lda, tau, u( 1, k+1 ), ldu,
563 DO 140 j = n - l + 1, n
564 DO 130 i = j - n + k + l + 1, m
571 work( 1 ) = dcmplx( lwkopt )
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 xerbla(SRNAME, INFO)
XERBLA
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
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 zlacpy(UPLO, M, N, A, LDA, B, LDB)
ZLACPY copies all or part of one two-dimensional array to another.
subroutine zgerq2(M, N, A, LDA, TAU, WORK, INFO)
ZGERQ2 computes the RQ factorization of a general rectangular matrix using an unblocked algorithm...
subroutine zung2r(M, N, K, A, LDA, TAU, WORK, INFO)
ZUNG2R
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 zgeqp3(M, N, A, LDA, JPVT, TAU, WORK, LWORK, RWORK, INFO)
ZGEQP3
subroutine zgeqr2(M, N, A, LDA, TAU, WORK, INFO)
ZGEQR2 computes the QR factorization of a general rectangular matrix using an unblocked algorithm...