174 SUBROUTINE dgrqts( M, P, N, 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', m, n, a, lda, af, lda )
223 CALL dlacpy(
'Full', p, n, b, ldb, bf, ldb )
225 anorm = max( dlange(
'1', m, n, a, lda, rwork ), unfl )
226 bnorm = max( dlange(
'1', p, n, b, ldb, rwork ), unfl )
230 CALL dggrqf( m, p, n, af, lda, taua, bf, ldb, taub, work, lwork,
235 CALL dlaset(
'Full', n, n, rogue, rogue, q, lda )
237 IF( m.GT.0 .AND. m.LT.n )
238 $
CALL dlacpy(
'Full', m, n-m, af, lda, q( n-m+1, 1 ), lda )
240 $
CALL dlacpy(
'Lower', m-1, m-1, af( 2, n-m+1 ), lda,
241 $ q( n-m+2, n-m+1 ), lda )
244 $
CALL dlacpy(
'Lower', n-1, n-1, af( m-n+2, 1 ), lda,
247 CALL dorgrq( n, n, min( m, n ), q, lda, taua, work, lwork, info )
251 CALL dlaset(
'Full', p, p, rogue, rogue, z, ldb )
253 $
CALL dlacpy(
'Lower', p-1, n, bf( 2, 1 ), ldb, z( 2, 1 ), ldb )
254 CALL dorgqr( p, p, min( p, n ), z, ldb, taub, work, lwork, info )
258 CALL dlaset(
'Full', m, n, zero, zero, r, lda )
260 CALL dlacpy(
'Upper', m, m, af( 1, n-m+1 ), lda, r( 1, n-m+1 ),
263 CALL dlacpy(
'Full', m-n, n, af, lda, r, lda )
264 CALL dlacpy(
'Upper', n, n, af( m-n+1, 1 ), lda, r( m-n+1, 1 ),
270 CALL dlaset(
'Full', p, n, zero, zero, t, ldb )
271 CALL dlacpy(
'Upper', p, n, bf, ldb, t, ldb )
275 CALL dgemm(
'No transpose',
'Transpose', m, n, n, -one, a, lda, q,
280 resid = dlange(
'1', m, n, r, lda, rwork )
281 IF( anorm.GT.zero )
THEN
282 result( 1 ) = ( ( resid / dble( max( 1, m, n ) ) ) / anorm ) /
290 CALL dgemm(
'Transpose',
'No transpose', p, n, p, one, z, ldb, b,
291 $ ldb, zero, bwk, ldb )
292 CALL dgemm(
'No transpose',
'No transpose', p, n, n, one, t, ldb,
293 $ q, lda, -one, bwk, ldb )
297 resid = dlange(
'1', p, n, bwk, ldb, rwork )
298 IF( bnorm.GT.zero )
THEN
299 result( 2 ) = ( ( resid / dble( max( 1, p, m ) ) ) / bnorm ) /
307 CALL dlaset(
'Full', n, n, zero, one, r, lda )
308 CALL dsyrk(
'Upper',
'No Transpose', n, n, -one, q, lda, one, r,
313 resid = dlansy(
'1',
'Upper', n, r, lda, rwork )
314 result( 3 ) = ( resid / dble( max( 1, n ) ) ) / ulp
318 CALL dlaset(
'Full', p, p, zero, one, t, ldb )
319 CALL dsyrk(
'Upper',
'Transpose', p, p, -one, z, ldb, one, t,
324 resid = dlansy(
'1',
'Upper', p, t, ldb, rwork )
325 result( 4 ) = ( resid / dble( max( 1, p ) ) ) / ulp
subroutine dgrqts(m, p, n, a, af, q, r, lda, taua, b, bf, z, t, bwk, ldb, taub, work, lwork, rwork, result)
DGRQTS
subroutine dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
DGEMM
subroutine dggrqf(m, p, n, a, lda, taua, b, ldb, taub, work, lwork, info)
DGGRQF
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