174 SUBROUTINE dgqrts( N, M, P, A, AF, Q, R, LDA, TAUA, B, BF, Z, T,
175 $ BWK, LDB, TAUB, WORK, LWORK, RWORK, RESULT )
182 INTEGER LDA, LDB, LWORK, M, N, P
185 DOUBLE PRECISION A( LDA, * ), AF( LDA, * ), B( LDB, * ),
186 $ bf( ldb, * ), bwk( ldb, * ), q( lda, * ),
187 $ r( lda, * ), result( 4 ), rwork( * ),
188 $ t( ldb, * ), taua( * ), taub( * ),
189 $ work( lwork ), z( ldb, * )
195 DOUBLE PRECISION ZERO, ONE
196 parameter( zero = 0.0d+0, one = 1.0d+0 )
197 DOUBLE PRECISION ROGUE
198 parameter( rogue = -1.0d+10 )
202 DOUBLE PRECISION ANORM, BNORM, RESID, ULP, UNFL
205 DOUBLE PRECISION DLAMCH, DLANGE, DLANSY
206 EXTERNAL dlamch, dlange, dlansy
213 INTRINSIC dble, max, min
217 ulp = dlamch(
'Precision' )
218 unfl = dlamch(
'Safe minimum' )
222 CALL dlacpy(
'Full', n, m, a, lda, af, lda )
223 CALL dlacpy(
'Full', n, p, b, ldb, bf, ldb )
225 anorm = max( dlange(
'1', n, m, a, lda, rwork ), unfl )
226 bnorm = max( dlange(
'1', n, p, b, ldb, rwork ), unfl )
230 CALL dggqrf( n, m, p, af, lda, taua, bf, ldb, taub, work, lwork,
235 CALL dlaset(
'Full', n, n, rogue, rogue, q, lda )
236 CALL dlacpy(
'Lower', n-1, m, af( 2, 1 ), lda, q( 2, 1 ), lda )
237 CALL dorgqr( n, n, min( n, m ), q, lda, taua, work, lwork, info )
241 CALL dlaset(
'Full', p, p, rogue, rogue, z, ldb )
243 IF( n.GT.0 .AND. n.LT.p )
244 $
CALL dlacpy(
'Full', n, p-n, bf, ldb, z( p-n+1, 1 ), ldb )
246 $
CALL dlacpy(
'Lower', n-1, n-1, bf( 2, p-n+1 ), ldb,
247 $ z( p-n+2, p-n+1 ), ldb )
250 $
CALL dlacpy(
'Lower', p-1, p-1, bf( n-p+2, 1 ), ldb,
253 CALL dorgrq( p, p, min( n, p ), z, ldb, taub, work, lwork, info )
257 CALL dlaset(
'Full', n, m, zero, zero, r, lda )
258 CALL dlacpy(
'Upper', n, m, af, lda, r, lda )
262 CALL dlaset(
'Full', n, p, zero, zero, t, ldb )
264 CALL dlacpy(
'Upper', n, n, bf( 1, p-n+1 ), ldb, t( 1, p-n+1 ),
267 CALL dlacpy(
'Full', n-p, p, bf, ldb, t, ldb )
268 CALL dlacpy(
'Upper', p, p, bf( n-p+1, 1 ), ldb, t( n-p+1, 1 ),
274 CALL dgemm(
'Transpose',
'No transpose', n, m, n, -one, q, lda, a,
279 resid = dlange(
'1', n, m, r, lda, rwork )
280 IF( anorm.GT.zero )
THEN
281 result( 1 ) = ( ( resid / dble( max( 1, m, n ) ) ) / anorm ) /
289 CALL dgemm(
'No Transpose',
'No transpose', n, p, p, one, t, ldb,
290 $ z, ldb, zero, bwk, ldb )
291 CALL dgemm(
'Transpose',
'No transpose', n, p, n, -one, q, lda, b,
292 $ ldb, one, bwk, ldb )
296 resid = dlange(
'1', n, p, bwk, ldb, rwork )
297 IF( bnorm.GT.zero )
THEN
298 result( 2 ) = ( ( resid / dble( max( 1, p, n ) ) ) / bnorm ) /
306 CALL dlaset(
'Full', n, n, zero, one, r, lda )
307 CALL dsyrk(
'Upper',
'Transpose', n, n, -one, q, lda, one, r,
312 resid = dlansy(
'1',
'Upper', n, r, lda, rwork )
313 result( 3 ) = ( resid / dble( max( 1, n ) ) ) / ulp
317 CALL dlaset(
'Full', p, p, zero, one, t, ldb )
318 CALL dsyrk(
'Upper',
'Transpose', p, p, -one, z, ldb, one, t,
323 resid = dlansy(
'1',
'Upper', p, t, ldb, rwork )
324 result( 4 ) = ( resid / dble( max( 1, p ) ) ) / ulp
subroutine dgqrts(n, m, p, a, af, q, r, lda, taua, b, bf, z, t, bwk, ldb, taub, work, lwork, rwork, result)
DGQRTS
subroutine dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
DGEMM
subroutine dggqrf(n, m, p, a, lda, taua, b, ldb, taub, work, lwork, info)
DGGQRF
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.
subroutine dorgqr(m, n, k, a, lda, tau, work, lwork, info)
DORGQR
subroutine dorgrq(m, n, k, a, lda, tau, work, lwork, info)
DORGRQ