126 INTEGER M, N, MB1, NB1, NB2
128 DOUBLE PRECISION RESULT(6)
134 DOUBLE PRECISION,
ALLOCATABLE :: A(:,:), AF(:,:), Q(:,:), R(:,:),
135 $ RWORK(:), WORK( : ), T1(:,:), T2(:,:), DIAG(:),
136 $ C(:,:), CF(:,:), D(:,:), DF(:,:)
139 DOUBLE PRECISION ONE, ZERO
140 parameter( zero = 0.0d+0, one = 1.0d+0 )
144 INTEGER INFO, I, J, K, L, LWORK, NB1_UB, NB2_UB, NRB
145 DOUBLE PRECISION ANORM, EPS, RESID, CNORM, DNORM
149 DOUBLE PRECISION WORKQUERY( 1 )
152 DOUBLE PRECISION DLAMCH, DLANGE, DLANSY
153 EXTERNAL dlamch, dlange, dlansy
160 INTRINSIC ceiling, dble, max, min
163 CHARACTER(LEN=32) SRNAMT
166 COMMON / srmnamc / srnamt
169 DATA iseed / 1988, 1989, 1990, 1991 /
175 eps = dlamch(
'Epsilon' )
181 ALLOCATE ( a(m,n), af(m,n), q(l,l), r(m,l), rwork(l),
188 CALL dlarnv( 2, iseed, m, a( 1, j ) )
193 CALL dlarnv( 2, iseed, m/2, a( m/4, j ) )
197 CALL dlacpy(
'Full', m, n, a, m, af, m )
201 nrb = max( 1, ceiling( dble( m - n ) / dble( mb1 - n ) ) )
203 ALLOCATE ( t1( nb1, n * nrb ) )
204 ALLOCATE ( t2( nb2, n ) )
205 ALLOCATE ( diag( n ) )
211 nb1_ub = min( nb1, n)
215 nb2_ub = min( nb2, n)
217 CALL dlatsqr( m, n, mb1, nb1_ub, af, m, t1, nb1,
218 $ workquery, -1, info )
219 lwork = int( workquery( 1 ) )
220 CALL dorgtsqr( m, n, mb1, nb1, af, m, t1, nb1, workquery, -1,
223 lwork = max( lwork, int( workquery( 1 ) ) )
228 lwork = max( lwork, nb2_ub * n, nb2_ub * m )
230 ALLOCATE ( work( lwork ) )
240 CALL dlatsqr( m, n, mb1, nb1_ub, af, m, t1, nb1, work, lwork,
246 CALL dlacpy(
'U', n, n, af, m, r, m )
251 CALL dorgtsqr( m, n, mb1, nb1, af, m, t1, nb1, work, lwork,
258 CALL dorhr_col( m, n, nb2, af, m, t2, nb2, diag, info )
268 CALL dlacpy(
'U', n, n, r, m, af, m )
271 IF( diag( i ).EQ.-one )
THEN
272 CALL dscal( n+1-i, -one, af( i, i ), m )
281 CALL dlaset(
'Full', m, m, zero, one, q, m )
284 CALL dgemqrt(
'L',
'N', m, m, k, nb2_ub, af, m, t2, nb2, q, m,
289 CALL dlaset(
'Full', m, n, zero, zero, r, m )
291 CALL dlacpy(
'Upper', m, n, af, m, r, m )
296 CALL dgemm(
'T',
'N', m, n, m, -one, q, m, a, m, one, r, m )
298 anorm = dlange(
'1', m, n, a, m, rwork )
299 resid = dlange(
'1', m, n, r, m, rwork )
300 IF( anorm.GT.zero )
THEN
301 result( 1 ) = resid / ( eps * max( 1, m ) * anorm )
309 CALL dlaset(
'Full', m, m, zero, one, r, m )
310 CALL dsyrk(
'U',
'T', m, m, -one, q, m, one, r, m )
311 resid = dlansy(
'1',
'Upper', m, r, m, rwork )
312 result( 2 ) = resid / ( eps * max( 1, m ) )
317 CALL dlarnv( 2, iseed, m, c( 1, j ) )
319 cnorm = dlange(
'1', m, n, c, m, rwork )
320 CALL dlacpy(
'Full', m, n, c, m, cf, m )
325 CALL dgemqrt(
'L',
'N', m, n, k, nb2_ub, af, m, t2, nb2, cf, m,
331 CALL dgemm(
'N',
'N', m, n, m, -one, q, m, c, m, one, cf, m )
332 resid = dlange(
'1', m, n, cf, m, rwork )
333 IF( cnorm.GT.zero )
THEN
334 result( 3 ) = resid / ( eps * max( 1, m ) * cnorm )
341 CALL dlacpy(
'Full', m, n, c, m, cf, m )
346 CALL dgemqrt(
'L',
'T', m, n, k, nb2_ub, af, m, t2, nb2, cf, m,
352 CALL dgemm(
'T',
'N', m, n, m, -one, q, m, c, m, one, cf, m )
353 resid = dlange(
'1', m, n, cf, m, rwork )
354 IF( cnorm.GT.zero )
THEN
355 result( 4 ) = resid / ( eps * max( 1, m ) * cnorm )
363 CALL dlarnv( 2, iseed, n, d( 1, j ) )
365 dnorm = dlange(
'1', n, m, d, n, rwork )
366 CALL dlacpy(
'Full', n, m, d, n, df, n )
371 CALL dgemqrt(
'R',
'N', n, m, k, nb2_ub, af, m, t2, nb2, df, n,
377 CALL dgemm(
'N',
'N', n, m, m, -one, d, n, q, m, one, df, n )
378 resid = dlange(
'1', n, m, df, n, rwork )
379 IF( dnorm.GT.zero )
THEN
380 result( 5 ) = resid / ( eps * max( 1, m ) * dnorm )
387 CALL dlacpy(
'Full', n, m, d, n, df, n )
392 CALL dgemqrt(
'R',
'T', n, m, k, nb2_ub, af, m, t2, nb2, df, n,
398 CALL dgemm(
'N',
'T', n, m, m, -one, d, n, q, m, one, df, n )
399 resid = dlange(
'1', n, m, df, n, rwork )
400 IF( dnorm.GT.zero )
THEN
401 result( 6 ) = resid / ( eps * max( 1, m ) * dnorm )
408 DEALLOCATE ( a, af, q, r, rwork, work, t1, t2, diag,
subroutine dorhr_col01(m, n, mb1, nb1, nb2, result)
DORHR_COL01
subroutine dgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
DGEMM
subroutine dgemqrt(side, trans, m, n, k, nb, v, ldv, t, ldt, c, ldc, work, info)
DGEMQRT
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 dlarnv(idist, iseed, n, x)
DLARNV returns a vector of random numbers from a uniform or normal distribution.
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 dlatsqr(m, n, mb, nb, a, lda, t, ldt, work, lwork, info)
DLATSQR
subroutine dscal(n, da, dx, incx)
DSCAL
subroutine dorgtsqr(m, n, mb, nb, a, lda, t, ldt, work, lwork, info)
DORGTSQR
subroutine dorhr_col(m, n, nb, a, lda, t, ldt, d, info)
DORHR_COL