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 xerbla(srname, info)
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.
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
subroutine zlacpy(uplo, m, n, a, lda, b, ldb)
ZLACPY copies all or part of one two-dimensional array to another.
subroutine zlapmt(forwrd, m, n, x, ldx, k)
ZLAPMT performs a forward or backward permutation of the columns of a matrix.
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 zung2r(m, n, k, a, lda, tau, work, info)
ZUNG2R
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 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...