253 SUBROUTINE dggsvp( JOBU, JOBV, JOBQ, M, P, N, A, LDA, B, LDB,
254 $ TOLA, TOLB, K, L, U, LDU, V, LDV, Q, LDQ,
255 $ IWORK, TAU, WORK, INFO )
262 CHARACTER JOBQ, JOBU, JOBV
263 INTEGER INFO, K, L, LDA, LDB, LDQ, LDU, LDV, M, N, P
264 DOUBLE PRECISION TOLA, TOLB
268 DOUBLE PRECISION A( LDA, * ), B( LDB, * ), Q( LDQ, * ),
269 $ tau( * ), u( ldu, * ), v( ldv, * ), work( * )
275 DOUBLE PRECISION ZERO, ONE
276 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0 )
279 LOGICAL FORWRD, WANTQ, WANTU, WANTV
291 INTRINSIC abs, max, min
297 wantu = lsame( jobu,
'U' )
298 wantv = lsame( jobv,
'V' )
299 wantq = lsame( jobq,
'Q' )
303 IF( .NOT.( wantu .OR. lsame( jobu,
'N' ) ) )
THEN
305 ELSE IF( .NOT.( wantv .OR. lsame( jobv,
'N' ) ) )
THEN
307 ELSE IF( .NOT.( wantq .OR. lsame( jobq,
'N' ) ) )
THEN
309 ELSE IF( m.LT.0 )
THEN
311 ELSE IF( p.LT.0 )
THEN
313 ELSE IF( n.LT.0 )
THEN
315 ELSE IF( lda.LT.max( 1, m ) )
THEN
317 ELSE IF( ldb.LT.max( 1, p ) )
THEN
319 ELSE IF( ldu.LT.1 .OR. ( wantu .AND. ldu.LT.m ) )
THEN
321 ELSE IF( ldv.LT.1 .OR. ( wantv .AND. ldv.LT.p ) )
THEN
323 ELSE IF( ldq.LT.1 .OR. ( wantq .AND. ldq.LT.n ) )
THEN
327 CALL xerbla(
'DGGSVP', -info )
337 CALL dgeqpf( p, n, b, ldb, iwork, tau, work, info )
341 CALL dlapmt( forwrd, m, n, a, lda, iwork )
346 DO 20 i = 1, min( p, n )
347 IF( abs( b( i, i ) ).GT.tolb )
355 CALL dlaset(
'Full', p, p, zero, zero, v, ldv )
357 $
CALL dlacpy(
'Lower', p-1, n, b( 2, 1 ), ldb, v( 2, 1 ),
359 CALL dorg2r( p, p, min( p, n ), v, ldv, tau, work, info )
370 $
CALL dlaset(
'Full', p-l, n, zero, zero, b( l+1, 1 ), ldb )
376 CALL dlaset(
'Full', n, n, zero, one, q, ldq )
377 CALL dlapmt( forwrd, n, n, q, ldq, iwork )
380 IF( p.GE.l .AND. n.NE.l )
THEN
384 CALL dgerq2( l, n, b, ldb, tau, work, info )
388 CALL dormr2(
'Right',
'Transpose', m, n, l, b, ldb, tau, a,
395 CALL dormr2(
'Right',
'Transpose', n, n, l, b, ldb, tau, q,
401 CALL dlaset(
'Full', l, n-l, zero, zero, b, ldb )
402 DO 60 j = n - l + 1, n
403 DO 50 i = j - n + l + 1, l
421 CALL dgeqpf( m, n-l, a, lda, iwork, tau, work, info )
426 DO 80 i = 1, min( m, n-l )
427 IF( abs( a( i, i ) ).GT.tola )
433 CALL dorm2r(
'Left',
'Transpose', m, l, min( m, n-l ), a, lda,
434 $ tau, a( 1, n-l+1 ), lda, work, info )
440 CALL dlaset(
'Full', m, m, zero, zero, u, ldu )
442 $
CALL dlacpy(
'Lower', m-1, n-l, a( 2, 1 ), lda, u( 2, 1 ),
444 CALL dorg2r( m, m, min( m, n-l ), u, ldu, tau, work, info )
451 CALL dlapmt( forwrd, n, n-l, q, ldq, iwork )
463 $
CALL dlaset(
'Full', m-k, n-l, zero, zero, a( k+1, 1 ), lda )
469 CALL dgerq2( k, n-l, a, lda, tau, work, info )
475 CALL dormr2(
'Right',
'Transpose', n, n-l, k, a, lda, tau,
476 $ q, ldq, work, info )
481 CALL dlaset(
'Full', k, n-l-k, zero, zero, a, lda )
482 DO 120 j = n - l - k + 1, n - l
483 DO 110 i = j - n + l + k + 1, k
494 CALL dgeqr2( m-k, l, a( k+1, n-l+1 ), lda, tau, work, info )
500 CALL dorm2r(
'Right',
'No transpose', m, m-k, min( m-k, l ),
501 $ a( k+1, n-l+1 ), lda, tau, u( 1, k+1 ), ldu,
507 DO 140 j = n - l + 1, n
508 DO 130 i = j - n + k + l + 1, m
subroutine xerbla(srname, info)
subroutine dgeqpf(m, n, a, lda, jpvt, tau, work, info)
DGEQPF
subroutine dggsvp(jobu, jobv, jobq, m, p, n, a, lda, b, ldb, tola, tolb, k, l, u, ldu, v, ldv, q, ldq, iwork, tau, work, info)
DGGSVP
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 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...