269 SUBROUTINE dggsvp3( JOBU, JOBV, JOBQ, M, P, N, A, LDA, B, LDB,
270 $ TOLA, TOLB, K, L, U, LDU, V, LDV, Q, LDQ,
271 $ IWORK, TAU, WORK, LWORK, INFO )
280 CHARACTER JOBQ, JOBU, JOBV
281 INTEGER INFO, K, L, LDA, LDB, LDQ, LDU, LDV, M, N, P,
283 DOUBLE PRECISION TOLA, TOLB
287 DOUBLE PRECISION A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
288 $ tau( * ), u( ldu, * ), v( ldv, * ), work( * )
294 DOUBLE PRECISION ZERO, ONE
295 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0 )
298 LOGICAL FORWRD, WANTQ, WANTU, WANTV, LQUERY
310 INTRINSIC abs, max, min
316 wantu = lsame( jobu,
'U' )
317 wantv = lsame( jobv,
'V' )
318 wantq = lsame( jobq,
'Q' )
320 lquery = ( lwork.EQ.-1 )
326 IF( .NOT.( wantu .OR. lsame( jobu,
'N' ) ) )
THEN
328 ELSE IF( .NOT.( wantv .OR. lsame( jobv,
'N' ) ) )
THEN
330 ELSE IF( .NOT.( wantq .OR. lsame( jobq,
'N' ) ) )
THEN
332 ELSE IF( m.LT.0 )
THEN
334 ELSE IF( p.LT.0 )
THEN
336 ELSE IF( n.LT.0 )
THEN
338 ELSE IF( lda.LT.max( 1, m ) )
THEN
340 ELSE IF( ldb.LT.max( 1, p ) )
THEN
342 ELSE IF( ldu.LT.1 .OR. ( wantu .AND. ldu.LT.m ) )
THEN
344 ELSE IF( ldv.LT.1 .OR. ( wantv .AND. ldv.LT.p ) )
THEN
346 ELSE IF( ldq.LT.1 .OR. ( wantq .AND. ldq.LT.n ) )
THEN
348 ELSE IF( lwork.LT.1 .AND. .NOT.lquery )
THEN
355 CALL dgeqp3( p, n, b, ldb, iwork, tau, work, -1, info )
356 lwkopt = int( work( 1 ) )
358 lwkopt = max( lwkopt, p )
360 lwkopt = max( lwkopt, min( n, p ) )
361 lwkopt = max( lwkopt, m )
363 lwkopt = max( lwkopt, n )
365 CALL dgeqp3( m, n, a, lda, iwork, tau, work, -1, info )
366 lwkopt = max( lwkopt, int( work( 1 ) ) )
367 lwkopt = max( 1, lwkopt )
368 work( 1 ) = dble( lwkopt )
372 CALL xerbla(
'DGGSVP3', -info )
385 CALL dgeqp3( p, n, b, ldb, iwork, tau, work, lwork, info )
389 CALL dlapmt( forwrd, m, n, a, lda, iwork )
394 DO 20 i = 1, min( p, n )
395 IF( abs( b( i, i ) ).GT.tolb )
403 CALL dlaset(
'Full', p, p, zero, zero, v, ldv )
405 $
CALL dlacpy(
'Lower', p-1, n, b( 2, 1 ), ldb, v( 2, 1 ),
407 CALL dorg2r( p, p, min( p, n ), v, ldv, tau, work, info )
418 $
CALL dlaset(
'Full', p-l, n, zero, zero, b( l+1, 1 ), ldb )
424 CALL dlaset(
'Full', n, n, zero, one, q, ldq )
425 CALL dlapmt( forwrd, n, n, q, ldq, iwork )
428 IF( p.GE.l .AND. n.NE.l )
THEN
432 CALL dgerq2( l, n, b, ldb, tau, work, info )
436 CALL dormr2(
'Right',
'Transpose', m, n, l, b, ldb, tau, a,
443 CALL dormr2(
'Right',
'Transpose', n, n, l, b, ldb, tau, q,
449 CALL dlaset(
'Full', l, n-l, zero, zero, b, ldb )
450 DO 60 j = n - l + 1, n
451 DO 50 i = j - n + l + 1, l
469 CALL dgeqp3( m, n-l, a, lda, iwork, tau, work, lwork, info )
474 DO 80 i = 1, min( m, n-l )
475 IF( abs( a( i, i ) ).GT.tola )
481 CALL dorm2r(
'Left',
'Transpose', m, l, min( m, n-l ), a, lda,
482 $ tau, a( 1, n-l+1 ), lda, work, info )
488 CALL dlaset(
'Full', m, m, zero, zero, u, ldu )
490 $
CALL dlacpy(
'Lower', m-1, n-l, a( 2, 1 ), lda, u( 2, 1 ),
492 CALL dorg2r( m, m, min( m, n-l ), u, ldu, tau, work, info )
499 CALL dlapmt( forwrd, n, n-l, q, ldq, iwork )
511 $
CALL dlaset(
'Full', m-k, n-l, zero, zero, a( k+1, 1 ), lda )
517 CALL dgerq2( k, n-l, a, lda, tau, work, info )
523 CALL dormr2(
'Right',
'Transpose', n, n-l, k, a, lda, tau,
524 $ q, ldq, work, info )
529 CALL dlaset(
'Full', k, n-l-k, zero, zero, a, lda )
530 DO 120 j = n - l - k + 1, n - l
531 DO 110 i = j - n + l + k + 1, k
542 CALL dgeqr2( m-k, l, a( k+1, n-l+1 ), lda, tau, work, info )
548 CALL dorm2r(
'Right',
'No transpose', m, m-k, min( m-k, l ),
549 $ a( k+1, n-l+1 ), lda, tau, u( 1, k+1 ), ldu,
555 DO 140 j = n - l + 1, n
556 DO 130 i = j - n + k + l + 1, m
563 work( 1 ) = dble( lwkopt )
subroutine xerbla(srname, info)
subroutine dgeqp3(m, n, a, lda, jpvt, tau, work, lwork, info)
DGEQP3
subroutine dgeqr2(m, n, a, lda, tau, work, info)
DGEQR2 computes the QR factorization of a general rectangular matrix using an unblocked algorithm.
subroutine dgerq2(m, n, a, lda, tau, work, info)
DGERQ2 computes the RQ factorization of a general rectangular matrix using an unblocked algorithm.
subroutine dggsvp3(jobu, jobv, jobq, m, p, n, a, lda, b, ldb, tola, tolb, k, l, u, ldu, v, ldv, q, ldq, iwork, tau, work, lwork, info)
DGGSVP3
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
subroutine dlapmt(forwrd, m, n, x, ldx, k)
DLAPMT performs a forward or backward permutation of the columns of a matrix.
subroutine dlaset(uplo, m, n, alpha, beta, a, lda)
DLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine dorg2r(m, n, k, a, lda, tau, work, info)
DORG2R generates all or part of the orthogonal matrix Q from a QR factorization determined by sgeqrf ...
subroutine dorm2r(side, trans, m, n, k, a, lda, tau, c, ldc, work, info)
DORM2R multiplies a general matrix by the orthogonal matrix from a QR factorization determined by sge...
subroutine dormr2(side, trans, m, n, k, a, lda, tau, c, ldc, work, info)
DORMR2 multiplies a general matrix by the orthogonal matrix from a RQ factorization determined by sge...