97 INTEGER M, N, MB1, NB1, NB2
99 DOUBLE PRECISION RESULT(6)
105 DOUBLE PRECISION,
ALLOCATABLE :: A(:,:), AF(:,:), Q(:,:), R(:,:),
106 $ RWORK(:), WORK( : ), T1(:,:), T2(:,:), DIAG(:),
107 $ C(:,:), CF(:,:), D(:,:), DF(:,:)
110 DOUBLE PRECISION ONE, ZERO
111 parameter( zero = 0.0d+0, one = 1.0d+0 )
115 INTEGER INFO, I, J, K, L, LWORK, NB1_UB, NB2_UB, NRB
116 DOUBLE PRECISION ANORM, EPS, RESID, CNORM, DNORM
120 DOUBLE PRECISION WORKQUERY( 1 )
123 DOUBLE PRECISION DLAMCH, DLANGE, DLANSY
131 INTRINSIC ceiling, dble, max, min
134 CHARACTER(LEN=32) SRNAMT
137 COMMON / srmnamc / srnamt
140 DATA iseed / 1988, 1989, 1990, 1991 /
152 ALLOCATE ( a(m,n), af(m,n), q(l,l), r(m,l), rwork(l),
159 CALL dlarnv( 2, iseed, m, a( 1, j ) )
164 CALL dlarnv( 2, iseed, m/2, a( m/4, j ) )
168 CALL dlacpy(
'Full', m, n, a, m, af, m )
172 nrb = max( 1, ceiling( dble( m - n ) / dble( mb1 - n ) ) )
174 ALLOCATE ( t1( nb1, n * nrb ) )
175 ALLOCATE ( t2( nb2, n ) )
176 ALLOCATE ( diag( n ) )
182 nb1_ub = min( nb1, n)
186 nb2_ub = min( nb2, n)
188 CALL dlatsqr( m, n, mb1, nb1_ub, af, m, t1, nb1,
189 $ workquery, -1, info )
190 lwork = int( workquery( 1 ) )
191 CALL dorgtsqr( m, n, mb1, nb1, af, m, t1, nb1, workquery, -1,
194 lwork = max( lwork, int( workquery( 1 ) ) )
199 lwork = max( lwork, nb2_ub * n, nb2_ub * m )
201 ALLOCATE ( work( lwork ) )
211 CALL dlatsqr( m, n, mb1, nb1_ub, af, m, t1, nb1, work, lwork,
217 CALL dlacpy(
'U', n, n, af, m, r, m )
222 CALL dorgtsqr( m, n, mb1, nb1, af, m, t1, nb1, work, lwork,
229 CALL dorhr_col( m, n, nb2, af, m, t2, nb2, diag, info )
239 CALL dlacpy(
'U', n, n, r, m, af, m )
242 IF( diag( i ).EQ.-one )
THEN
243 CALL dscal( n+1-i, -one, af( i, i ), m )
252 CALL dlaset(
'Full', m, m, zero, one, q, m )
255 CALL dgemqrt(
'L',
'N', m, m, k, nb2_ub, af, m, t2, nb2, q, m,
260 CALL dlaset(
'Full', m, n, zero, zero, r, m )
262 CALL dlacpy(
'Upper', m, n, af, m, r, m )
267 CALL dgemm(
'T',
'N', m, n, m, -one, q, m, a, m, one, r, m )
269 anorm =
dlange(
'1', m, n, a, m, rwork )
270 resid =
dlange(
'1', m, n, r, m, rwork )
271 IF( anorm.GT.zero )
THEN
272 result( 1 ) = resid / ( eps * max( 1, m ) * anorm )
280 CALL dlaset(
'Full', m, m, zero, one, r, m )
281 CALL dsyrk(
'U',
'T', m, m, -one, q, m, one, r, m )
282 resid =
dlansy(
'1',
'Upper', m, r, m, rwork )
283 result( 2 ) = resid / ( eps * max( 1, m ) )
288 CALL dlarnv( 2, iseed, m, c( 1, j ) )
290 cnorm =
dlange(
'1', m, n, c, m, rwork )
291 CALL dlacpy(
'Full', m, n, c, m, cf, m )
296 CALL dgemqrt(
'L',
'N', m, n, k, nb2_ub, af, m, t2, nb2, cf, m,
302 CALL dgemm(
'N',
'N', m, n, m, -one, q, m, c, m, one, cf, m )
303 resid =
dlange(
'1', m, n, cf, m, rwork )
304 IF( cnorm.GT.zero )
THEN
305 result( 3 ) = resid / ( eps * max( 1, m ) * cnorm )
312 CALL dlacpy(
'Full', m, n, c, m, cf, m )
317 CALL dgemqrt(
'L',
'T', m, n, k, nb2_ub, af, m, t2, nb2, cf, m,
323 CALL dgemm(
'T',
'N', m, n, m, -one, q, m, c, m, one, cf, m )
324 resid =
dlange(
'1', m, n, cf, m, rwork )
325 IF( cnorm.GT.zero )
THEN
326 result( 4 ) = resid / ( eps * max( 1, m ) * cnorm )
334 CALL dlarnv( 2, iseed, n, d( 1, j ) )
336 dnorm =
dlange(
'1', n, m, d, n, rwork )
337 CALL dlacpy(
'Full', n, m, d, n, df, n )
342 CALL dgemqrt(
'R',
'N', n, m, k, nb2_ub, af, m, t2, nb2, df, n,
348 CALL dgemm(
'N',
'N', n, m, m, -one, d, n, q, m, one, df, n )
349 resid =
dlange(
'1', n, m, df, n, rwork )
350 IF( dnorm.GT.zero )
THEN
351 result( 5 ) = resid / ( eps * max( 1, m ) * dnorm )
358 CALL dlacpy(
'Full', n, m, d, n, df, n )
363 CALL dgemqrt(
'R',
'T', n, m, k, nb2_ub, af, m, t2, nb2, df, n,
369 CALL dgemm(
'N',
'T', n, m, m, -one, d, n, q, m, one, df, n )
370 resid =
dlange(
'1', n, m, df, n, rwork )
371 IF( dnorm.GT.zero )
THEN
372 result( 6 ) = resid / ( eps * max( 1, m ) * dnorm )
379 DEALLOCATE ( a, af, q, r, rwork, work, t1, t2, diag,