126 INTEGER M, N, MB1, NB1, NB2
134 REAL ,
ALLOCATABLE :: A(:,:), AF(:,:), Q(:,:), R(:,:),
135 $ RWORK(:), WORK( : ), T1(:,:), T2(:,:), DIAG(:),
136 $ C(:,:), CF(:,:), D(:,:), DF(:,:)
140 parameter( zero = 0.0e+0, one = 1.0e+0 )
144 INTEGER INFO, I, J, K, L, LWORK, NB1_UB, NB2_UB, NRB
145 REAL ANORM, EPS, RESID, CNORM, DNORM
152 REAL SLAMCH, SLANGE, SLANSY
160 INTRINSIC ceiling, real, max, min
163 CHARACTER(LEN=32) SRNAMT
166 COMMON / srmnamc / srnamt
169 DATA iseed / 1988, 1989, 1990, 1991 /
181 ALLOCATE ( a(m,n), af(m,n), q(l,l), r(m,l), rwork(l),
188 CALL slarnv( 2, iseed, m, a( 1, j ) )
193 CALL slarnv( 2, iseed, m/2, a( m/4, j ) )
197 CALL slacpy(
'Full', m, n, a, m, af, m )
201 nrb = max( 1, ceiling( real( m - n ) / real( 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 slatsqr( m, n, mb1, nb1_ub, af, m, t1, nb1,
218 $ workquery, -1, info )
219 lwork = int( workquery( 1 ) )
220 CALL sorgtsqr( 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 slatsqr( m, n, mb1, nb1_ub, af, m, t1, nb1, work, lwork,
246 CALL slacpy(
'U', n, n, af, m, r, m )
251 CALL sorgtsqr( m, n, mb1, nb1, af, m, t1, nb1, work, lwork,
258 CALL sorhr_col( m, n, nb2, af, m, t2, nb2, diag, info )
268 CALL slacpy(
'U', n, n, r, m, af, m )
271 IF( diag( i ).EQ.-one )
THEN
272 CALL sscal( n+1-i, -one, af( i, i ), m )
281 CALL slaset(
'Full', m, m, zero, one, q, m )
284 CALL sgemqrt(
'L',
'N', m, m, k, nb2_ub, af, m, t2, nb2, q, m,
289 CALL slaset(
'Full', m, n, zero, zero, r, m )
291 CALL slacpy(
'Upper', m, n, af, m, r, m )
296 CALL sgemm(
'T',
'N', m, n, m, -one, q, m, a, m, one, r, m )
298 anorm =
slange(
'1', m, n, a, m, rwork )
299 resid =
slange(
'1', m, n, r, m, rwork )
300 IF( anorm.GT.zero )
THEN
301 result( 1 ) = resid / ( eps * max( 1, m ) * anorm )
309 CALL slaset(
'Full', m, m, zero, one, r, m )
310 CALL ssyrk(
'U',
'T', m, m, -one, q, m, one, r, m )
311 resid =
slansy(
'1',
'Upper', m, r, m, rwork )
312 result( 2 ) = resid / ( eps * max( 1, m ) )
317 CALL slarnv( 2, iseed, m, c( 1, j ) )
319 cnorm =
slange(
'1', m, n, c, m, rwork )
320 CALL slacpy(
'Full', m, n, c, m, cf, m )
325 CALL sgemqrt(
'L',
'N', m, n, k, nb2_ub, af, m, t2, nb2, cf, m,
331 CALL sgemm(
'N',
'N', m, n, m, -one, q, m, c, m, one, cf, m )
332 resid =
slange(
'1', m, n, cf, m, rwork )
333 IF( cnorm.GT.zero )
THEN
334 result( 3 ) = resid / ( eps * max( 1, m ) * cnorm )
341 CALL slacpy(
'Full', m, n, c, m, cf, m )
346 CALL sgemqrt(
'L',
'T', m, n, k, nb2_ub, af, m, t2, nb2, cf, m,
352 CALL sgemm(
'T',
'N', m, n, m, -one, q, m, c, m, one, cf, m )
353 resid =
slange(
'1', m, n, cf, m, rwork )
354 IF( cnorm.GT.zero )
THEN
355 result( 4 ) = resid / ( eps * max( 1, m ) * cnorm )
363 CALL slarnv( 2, iseed, n, d( 1, j ) )
365 dnorm =
slange(
'1', n, m, d, n, rwork )
366 CALL slacpy(
'Full', n, m, d, n, df, n )
371 CALL sgemqrt(
'R',
'N', n, m, k, nb2_ub, af, m, t2, nb2, df, n,
377 CALL sgemm(
'N',
'N', n, m, m, -one, d, n, q, m, one, df, n )
378 resid =
slange(
'1', n, m, df, n, rwork )
379 IF( dnorm.GT.zero )
THEN
380 result( 5 ) = resid / ( eps * max( 1, m ) * dnorm )
387 CALL slacpy(
'Full', n, m, d, n, df, n )
392 CALL sgemqrt(
'R',
'T', n, m, k, nb2_ub, af, m, t2, nb2, df, n,
398 CALL sgemm(
'N',
'T', n, m, m, -one, d, n, q, m, one, df, n )
399 resid =
slange(
'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 slarnv(IDIST, ISEED, N, X)
SLARNV returns a vector of random numbers from a uniform or normal distribution.
subroutine slaset(UPLO, M, N, ALPHA, BETA, A, LDA)
SLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine slacpy(UPLO, M, N, A, LDA, B, LDB)
SLACPY copies all or part of one two-dimensional array to another.
real function slange(NORM, M, N, A, LDA, WORK)
SLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
subroutine sgemqrt(SIDE, TRANS, M, N, K, NB, V, LDV, T, LDT, C, LDC, WORK, INFO)
SGEMQRT
real function slansy(NORM, UPLO, N, A, LDA, WORK)
SLANSY returns the value of the 1-norm, or the Frobenius norm, or the infinity norm,...
subroutine sscal(N, SA, SX, INCX)
SSCAL
subroutine ssyrk(UPLO, TRANS, N, K, ALPHA, A, LDA, BETA, C, LDC)
SSYRK
subroutine sgemm(TRANSA, TRANSB, M, N, K, ALPHA, A, LDA, B, LDB, BETA, C, LDC)
SGEMM
real function slamch(CMACH)
SLAMCH
subroutine slatsqr(M, N, MB, NB, A, LDA, T, LDT, WORK, LWORK, INFO)
SLATSQR
subroutine sorgtsqr(M, N, MB, NB, A, LDA, T, LDT, WORK, LWORK, INFO)
SORGTSQR
subroutine sorhr_col(M, N, NB, A, LDA, T, LDT, D, INFO)
SORHR_COL