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, , LDA, LDB, LDQ, LDU, LDV, M, N, P,
289 DOUBLE PRECISION TOLA, TOLB
293 DOUBLE PRECISION ( * )
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 )
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 )