267 SUBROUTINE sggsvp3( JOBU, JOBV, JOBQ, M, P, N, A, LDA, B, LDB,
268 $ TOLA, TOLB, K, L, U, LDU, V, LDV, Q, LDQ,
269 $ IWORK, TAU, WORK, LWORK, INFO )
278 CHARACTER JOBQ, JOBU, JOBV
279 INTEGER INFO, K, L, LDA, LDB, LDQ, LDU, LDV, M, N, P,
285 REAL A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
286 $ tau( * ), u( ldu, * ), v( ldv, * ), work( * )
293 PARAMETER ( ZERO = 0.0e+0, one = 1.0e+0 )
296 LOGICAL FORWRD, WANTQ, WANTU, WANTV, LQUERY
303 EXTERNAL sroundup_lwork
311 INTRINSIC abs, max, min
317 wantu = lsame( jobu,
'U' )
318 wantv = lsame( jobv,
'V' )
319 wantq = lsame( jobq,
'Q' )
321 lquery = ( lwork.EQ.-1 )
327 IF( .NOT.( wantu .OR. lsame( jobu,
'N' ) ) )
THEN
329 ELSE IF( .NOT.( wantv .OR. lsame( jobv,
'N' ) ) )
THEN
331 ELSE IF( .NOT.( wantq .OR. lsame( jobq,
'N' ) ) )
THEN
333 ELSE IF( m.LT.0 )
THEN
335 ELSE IF( p.LT.0 )
THEN
337 ELSE IF( n.LT.0 )
THEN
339 ELSE IF( lda.LT.max( 1, m ) )
THEN
341 ELSE IF( ldb.LT.max( 1, p ) )
THEN
343 ELSE IF( ldu.LT.1 .OR. ( wantu .AND. ldu.LT.m ) )
THEN
345 ELSE IF( ldv.LT.1 .OR. ( wantv .AND. ldv.LT.p ) )
THEN
347 ELSE IF( ldq.LT.1 .OR. ( wantq .AND. ldq.LT.n ) )
THEN
349 ELSE IF( lwork.LT.1 .AND. .NOT.lquery )
THEN
356 CALL sgeqp3( p, n, b, ldb, iwork, tau, work, -1, info )
357 lwkopt = int( work( 1 ) )
359 lwkopt = max( lwkopt, p )
361 lwkopt = max( lwkopt, min( n, p ) )
362 lwkopt = max( lwkopt, m )
364 lwkopt = max( lwkopt, n )
366 CALL sgeqp3( m, n, a, lda, iwork, tau, work, -1, info )
367 lwkopt = max( lwkopt, int( work( 1 ) ) )
368 lwkopt = max( 1, lwkopt )
369 work( 1 ) = sroundup_lwork( lwkopt )
373 CALL xerbla(
'SGGSVP3', -info )
386 CALL sgeqp3( p, n, b, ldb, iwork, tau, work, lwork, info )
390 CALL slapmt( forwrd, m, n, a, lda, iwork )
395 DO 20 i = 1, min( p, n )
396 IF( abs( b( i, i ) ).GT.tolb )
404 CALL slaset(
'Full', p, p, zero, zero, v, ldv )
406 $
CALL slacpy(
'Lower', p-1, n, b( 2, 1 ), ldb, v( 2, 1 ),
408 CALL sorg2r( p, p, min( p, n ), v, ldv, tau, work, info )
419 $
CALL slaset(
'Full', p-l, n, zero, zero, b( l+1, 1 ), ldb )
425 CALL slaset(
'Full', n, n, zero, one, q, ldq )
426 CALL slapmt( forwrd, n, n, q, ldq, iwork )
429 IF( p.GE.l .AND. n.NE.l )
THEN
433 CALL sgerq2( l, n, b, ldb, tau, work, info )
437 CALL sormr2(
'Right',
'Transpose', m, n, l, b, ldb, tau, a,
444 CALL sormr2(
'Right',
'Transpose', n, n, l, b, ldb, tau,
451 CALL slaset(
'Full', l, n-l, zero, zero, b, ldb )
452 DO 60 j = n - l + 1, n
453 DO 50 i = j - n + l + 1, l
471 CALL sgeqp3( m, n-l, a, lda, iwork, tau, work, lwork, info )
476 DO 80 i = 1, min( m, n-l )
477 IF( abs( a( i, i ) ).GT.tola )
483 CALL sorm2r(
'Left',
'Transpose', m, l, min( m, n-l ), a, lda,
484 $ tau, a( 1, n-l+1 ), lda, work, info )
490 CALL slaset(
'Full', m, m, zero, zero, u, ldu )
492 $
CALL slacpy(
'Lower', m-1, n-l, a( 2, 1 ), lda, u( 2,
495 CALL sorg2r( m, m, min( m, n-l ), u, ldu, tau, work, info )
502 CALL slapmt( forwrd, n, n-l, q, ldq, iwork )
514 $
CALL slaset(
'Full', m-k, n-l, zero, zero, a( k+1, 1 ),
521 CALL sgerq2( k, n-l, a, lda, tau, work, info )
527 CALL sormr2(
'Right',
'Transpose', n, n-l, k, a, lda,
529 $ q, ldq, work, info )
534 CALL slaset(
'Full', k, n-l-k, zero, zero, a, lda )
535 DO 120 j = n - l - k + 1, n - l
536 DO 110 i = j - n + l + k + 1, k
547 CALL sgeqr2( m-k, l, a( k+1, n-l+1 ), lda, tau, work, info )
553 CALL sorm2r(
'Right',
'No transpose', m, m-k, min( m-k,
555 $ a( k+1, n-l+1 ), lda, tau, u( 1, k+1 ), ldu,
561 DO 140 j = n - l + 1, n
562 DO 130 i = j - n + k + l + 1, m
569 work( 1 ) = sroundup_lwork( lwkopt )