206 SUBROUTINE zgsvts3( M, P, N, A, AF, LDA, B, BF, LDB, U, LDU, V,
207 $ LDV, Q, LDQ, ALPHA, BETA, R, LDR, IWORK, WORK,
208 $ LWORK, RWORK, RESULT )
215 INTEGER LDA, LDB, LDQ, LDR, LDU, LDV, LWORK, M, N, P
219 DOUBLE PRECISION ALPHA( * ), BETA( * ), RESULT( 6 ), RWORK( * )
220 COMPLEX*16 A( LDA, * ), AF( LDA, * ), B( LDB, * ),
221 $ bf( ldb, * ), q( ldq, * ), r( ldr, * ),
222 $ u( ldu, * ), v( ldv, * ), work( lwork )
228 DOUBLE PRECISION ZERO, ONE
229 PARAMETER ( ZERO = 0.0d+0, one = 1.0d+0 )
230 COMPLEX*16 CZERO, CONE
231 parameter( czero = ( 0.0d+0, 0.0d+0 ),
232 $ cone = ( 1.0d+0, 0.0d+0 ) )
235 INTEGER I, INFO, J, K, L
236 DOUBLE PRECISION ANORM, BNORM, RESID, TEMP, ULP, ULPINV, UNFL
239 DOUBLE PRECISION DLAMCH, ZLANGE, ZLANHE
240 EXTERNAL DLAMCH, ZLANGE, ZLANHE
246 INTRINSIC dble, max, min
250 ulp = dlamch(
'Precision' )
252 unfl = dlamch(
'Safe minimum' )
256 CALL zlacpy(
'Full', m, n, a, lda, af, lda )
257 CALL zlacpy(
'Full', p, n, b, ldb, bf, ldb )
259 anorm = max( zlange(
'1', m, n, a, lda, rwork ), unfl )
260 bnorm = max( zlange(
'1', p, n, b, ldb, rwork ), unfl )
264 CALL zggsvd3(
'U',
'V',
'Q', m, n, p, k, l, af, lda, bf, ldb,
265 $ alpha, beta, u, ldu, v, ldv, q, ldq, work, lwork,
266 $ rwork, iwork, info )
270 DO 20 i = 1, min( k+l, m )
272 r( i, j ) = af( i, n-k-l+j )
276 IF( m-k-l.LT.0 )
THEN
277 DO 40 i = m + 1, k + l
279 r( i, j ) = bf( i-k, n-k-l+j )
286 CALL zgemm(
'No transpose',
'No transpose', m, n, n, cone, a, lda,
287 $ q, ldq, czero, work, lda )
289 CALL zgemm(
'Conjugate transpose',
'No transpose', m, n, m, cone,
290 $ u, ldu, work, lda, czero, a, lda )
294 a( i, n-k-l+j ) = a( i, n-k-l+j ) - r( i, j )
298 DO 80 i = k + 1, min( k+l, m )
300 a( i, n-k-l+j ) = a( i, n-k-l+j ) - alpha( i )*r( i, j )
306 resid = zlange(
'1', m, n, a, lda, rwork )
307 IF( anorm.GT.zero )
THEN
308 result( 1 ) = ( ( resid / dble( max( 1, m, n ) ) ) / anorm ) /
316 CALL zgemm(
'No transpose',
'No transpose', p, n, n, cone, b, ldb,
317 $ q, ldq, czero, work, ldb )
319 CALL zgemm(
'Conjugate transpose',
'No transpose', p, n, p, cone,
320 $ v, ldv, work, ldb, czero, b, ldb )
324 b( i, n-l+j ) = b( i, n-l+j ) - beta( k+i )*r( k+i, k+j )
330 resid = zlange(
'1', p, n, b, ldb, rwork )
331 IF( bnorm.GT.zero )
THEN
332 result( 2 ) = ( ( resid / dble( max( 1, p, n ) ) ) / bnorm ) /
340 CALL zlaset(
'Full', m, m, czero, cone, work, ldq )
341 CALL zherk(
'Upper',
'Conjugate transpose', m, m, -one, u, ldu,
346 resid = zlanhe(
'1',
'Upper', m, work, ldu, rwork )
347 result( 3 ) = ( resid / dble( max( 1, m ) ) ) / ulp
351 CALL zlaset(
'Full', p, p, czero, cone, work, ldv )
352 CALL zherk(
'Upper',
'Conjugate transpose', p, p, -one, v, ldv,
357 resid = zlanhe(
'1',
'Upper', p, work, ldv, rwork )
358 result( 4 ) = ( resid / dble( max( 1, p ) ) ) / ulp
362 CALL zlaset(
'Full', n, n, czero, cone, work, ldq )
363 CALL zherk(
'Upper',
'Conjugate transpose', n, n, -one, q, ldq,
368 resid = zlanhe(
'1',
'Upper', n, work, ldq, rwork )
369 result( 5 ) = ( resid / dble( max( 1, n ) ) ) / ulp
373 CALL dcopy( n, alpha, 1, rwork, 1 )
374 DO 110 i = k + 1, min( k+l, m )
378 rwork( i ) = rwork( j )
384 DO 120 i = k + 1, min( k+l, m ) - 1
385 IF( rwork( i ).LT.rwork( i+1 ) )
386 $ result( 6 ) = ulpinv
subroutine dcopy(n, dx, incx, dy, incy)
DCOPY
subroutine zgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
ZGEMM
subroutine zggsvd3(jobu, jobv, jobq, m, n, p, k, l, a, lda, b, ldb, alpha, beta, u, ldu, v, ldv, q, ldq, work, lwork, rwork, iwork, info)
ZGGSVD3 computes the singular value decomposition (SVD) for OTHER matrices
subroutine zherk(uplo, trans, n, k, alpha, a, lda, beta, c, ldc)
ZHERK
subroutine zlacpy(uplo, m, n, a, lda, b, ldb)
ZLACPY copies all or part of one two-dimensional array to another.
subroutine zlaset(uplo, m, n, alpha, beta, a, lda)
ZLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine zgsvts3(m, p, n, a, af, lda, b, bf, ldb, u, ldu, v, ldv, q, ldq, alpha, beta, r, ldr, iwork, work, lwork, rwork, result)
ZGSVTS3