207 SUBROUTINE dgsvts3( M, P, N, A, AF, LDA, B, BF, LDB, U, LDU, V,
208 $ LDV, Q, LDQ, ALPHA, BETA, R, LDR, IWORK, WORK,
209 $ LWORK, RWORK, RESULT )
216 INTEGER LDA, LDB, LDQ, LDR, LDU, LDV, LWORK, M, N, P
220 DOUBLE PRECISION A( LDA, * ), AF( LDA, * ), ALPHA( * ),
221 $ b( ldb, * ), beta( * ), bf( ldb, * ),
222 $ q( ldq, * ), r( ldr, * ), result( 6 ),
223 $ rwork( * ), u( ldu, * ), v( ldv, * ),
230 DOUBLE PRECISION ZERO, ONE
231 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0 )
234 INTEGER I, INFO, J, K, L
235 DOUBLE PRECISION ANORM, BNORM, RESID, TEMP, ULP, ULPINV, UNFL
238 DOUBLE PRECISION DLAMCH, DLANGE, DLANSY
239 EXTERNAL DLAMCH, DLANGE, DLANSY
245 INTRINSIC dble, max, min
249 ulp = dlamch(
'Precision' )
251 unfl = dlamch(
'Safe minimum' )
255 CALL dlacpy(
'Full', m, n, a, lda, af, lda )
256 CALL dlacpy(
'Full', p, n, b, ldb, bf, ldb )
258 anorm = max( dlange(
'1', m, n, a, lda, rwork ), unfl )
259 bnorm = max( dlange(
'1', p, n, b, ldb, rwork ), unfl )
263 CALL dggsvd3(
'U',
'V',
'Q', m, n, p, k, l, af, lda, bf, ldb,
264 $ alpha, beta, u, ldu, v, ldv, q, ldq, work, lwork,
269 DO 20 i = 1, min( k+l, m )
271 r( i, j ) = af( i, n-k-l+j )
275 IF( m-k-l.LT.0 )
THEN
276 DO 40 i = m + 1, k + l
278 r( i, j ) = bf( i-k, n-k-l+j )
285 CALL dgemm(
'No transpose',
'No transpose', m, n, n, one, a, lda,
286 $ q, ldq, zero, work, lda )
288 CALL dgemm(
'Transpose',
'No transpose', m, n, m, one, u, ldu,
289 $ work, lda, zero, a, lda )
293 a( i, n-k-l+j ) = a( i, n-k-l+j ) - r( i, j )
297 DO 80 i = k + 1, min( k+l, m )
299 a( i, n-k-l+j ) = a( i, n-k-l+j ) - alpha( i )*r( i, j )
305 resid = dlange(
'1', m, n, a, lda, rwork )
307 IF( anorm.GT.zero )
THEN
308 result( 1 ) = ( ( resid / dble( max( 1, m, n ) ) ) / anorm ) /
316 CALL dgemm(
'No transpose',
'No transpose', p, n, n, one, b, ldb,
317 $ q, ldq, zero, work, ldb )
319 CALL dgemm(
'Transpose',
'No transpose', p, n, p, one, v, ldv,
320 $ work, ldb, zero, b, ldb )
324 b( i, n-l+j ) = b( i, n-l+j ) - beta( k+i )*r( k+i, k+j )
330 resid = dlange(
'1', p, n, b, ldb, rwork )
331 IF( bnorm.GT.zero )
THEN
332 result( 2 ) = ( ( resid / dble( max( 1, p, n ) ) ) / bnorm ) /
340 CALL dlaset(
'Full', m, m, zero, one, work, ldq )
341 CALL dsyrk(
'Upper',
'Transpose', m, m, -one, u, ldu, one, work,
346 resid = dlansy(
'1',
'Upper', m, work, ldu, rwork )
347 result( 3 ) = ( resid / dble( max( 1, m ) ) ) / ulp
351 CALL dlaset(
'Full', p, p, zero, one, work, ldv )
352 CALL dsyrk(
'Upper',
'Transpose', p, p, -one, v, ldv, one, work,
357 resid = dlansy(
'1',
'Upper', p, work, ldv, rwork )
358 result( 4 ) = ( resid / dble( max( 1, p ) ) ) / ulp
362 CALL dlaset(
'Full', n, n, zero, one, work, ldq )
363 CALL dsyrk(
'Upper',
'Transpose', n, n, -one, q, ldq, one, work,
368 resid = dlansy(
'1',
'Upper', n, work, ldq, rwork )
369 result( 5 ) = ( resid / dble( max( 1, n ) ) ) / ulp
373 CALL dcopy( n, alpha, 1, work, 1 )
374 DO 110 i = k + 1, min( k+l, m )
378 work( i ) = work( j )
384 DO 120 i = k + 1, min( k+l, m ) - 1
385 IF( work( i ).LT.work( i+1 ) )
386 $ result( 6 ) = ulpinv
subroutine dgsvts3(m, p, n, a, af, lda, b, bf, ldb, u, ldu, v, ldv, q, ldq, alpha, beta, r, ldr, iwork, work, lwork, rwork, result)
DGSVTS3
subroutine dcopy(n, dx, incx, dy, incy)
DCOPY
subroutine dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
DGEMM
subroutine dggsvd3(jobu, jobv, jobq, m, n, p, k, l, a, lda, b, ldb, alpha, beta, u, ldu, v, ldv, q, ldq, work, lwork, iwork, info)
DGGSVD3 computes the singular value decomposition (SVD) for OTHER matrices
subroutine dsyrk(uplo, trans, n, k, alpha, a, lda, beta, c, ldc)
DSYRK
subroutine dlacpy(uplo, m, n, a, lda, b, ldb)
DLACPY copies all or part of one two-dimensional array to another.
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.