120 IMPLICIT NONE
121
122
123
124
125
126
127 INTEGER M, N, MB1, NB1, NB2
128
129 REAL RESULT(6)
130
131
132
133
134
135 REAL , ALLOCATABLE :: A(:,:), AF(:,:), Q(:,:), R(:,:),
136 $ RWORK(:), WORK( : ), T1(:,:), T2(:,:), DIAG(:),
137 $ C(:,:), CF(:,:), D(:,:), DF(:,:)
138
139
140 REAL ONE, ZERO
141 parameter( zero = 0.0e+0, one = 1.0e+0 )
142
143
144 LOGICAL TESTZEROS
145 INTEGER INFO, J, K, L, LWORK, NB2_UB, NRB
146 REAL ANORM, EPS, RESID, CNORM, DNORM
147
148
149 INTEGER ISEED( 4 )
150 REAL WORKQUERY( 1 )
151
152
153 REAL SLAMCH, SLANGE, SLANSY
155
156
159
160
161 INTRINSIC ceiling, real, max, min
162
163
164 CHARACTER(LEN=32) SRNAMT
165
166
167 COMMON / srmnamc / srnamt
168
169
170 DATA iseed / 1988, 1989, 1990, 1991 /
171
172
173
174 testzeros = .false.
175
177 k = min( m, n )
178 l = max( m, n, 1)
179
180
181
182 ALLOCATE ( a(m,n), af(m,n), q(l,l), r(m,l), rwork(l),
183 $ c(m,n), cf(m,n),
184 $ d(n,m), df(n,m) )
185
186
187
188 DO j = 1, n
189 CALL slarnv( 2, iseed, m, a( 1, j ) )
190 END DO
191 IF( testzeros ) THEN
192 IF( m.GE.4 ) THEN
193 DO j = 1, n
194 CALL slarnv( 2, iseed, m/2, a( m/4, j ) )
195 END DO
196 END IF
197 END IF
198 CALL slacpy(
'Full', m, n, a, m, af, m )
199
200
201
202 nrb = max( 1, ceiling( real( m - n ) / real( mb1 - n ) ) )
203
204 ALLOCATE ( t1( nb1, n * nrb ) )
205 ALLOCATE ( t2( nb2, n ) )
206 ALLOCATE ( diag( n ) )
207
208
209
210
211
212 nb2_ub = min( nb2, n)
213
214 CALL sgetsqrhrt( m, n, mb1, nb1, nb2, af, m, t2, nb2,
215 $ workquery, -1, info )
216
217 lwork = int( workquery( 1 ) )
218
219
220
221
222 lwork = max( lwork, nb2_ub * n, nb2_ub * m )
223
224 ALLOCATE ( work( lwork ) )
225
226
227
228
229
230
231
232
233 srnamt = 'SGETSQRHRT'
234 CALL sgetsqrhrt( m, n, mb1, nb1, nb2, af, m, t2, nb2,
235 $ work, lwork, info )
236
237
238
239
240
241
242 CALL slaset(
'Full', m, m, zero, one, q, m )
243
244 srnamt = 'SGEMQRT'
245 CALL sgemqrt(
'L',
'N', m, m, k, nb2_ub, af, m, t2, nb2, q, m,
246 $ work, info )
247
248
249
250 CALL slaset(
'Full', m, n, zero, zero, r, m )
251
252 CALL slacpy(
'Upper', m, n, af, m, r, m )
253
254
255
256
257 CALL sgemm(
'T',
'N', m, n, m, -one, q, m, a, m, one, r, m )
258
259 anorm =
slange(
'1', m, n, a, m, rwork )
260 resid =
slange(
'1', m, n, r, m, rwork )
261 IF( anorm.GT.zero ) THEN
262 result( 1 ) = resid / ( eps * max( 1, m ) * anorm )
263 ELSE
264 result( 1 ) = zero
265 END IF
266
267
268
269
270 CALL slaset(
'Full', m, m, zero, one, r, m )
271 CALL ssyrk(
'U',
'T', m, m, -one, q, m, one, r, m )
272 resid =
slansy(
'1',
'Upper', m, r, m, rwork )
273 result( 2 ) = resid / ( eps * max( 1, m ) )
274
275
276
277 DO j = 1, n
278 CALL slarnv( 2, iseed, m, c( 1, j ) )
279 END DO
280 cnorm =
slange(
'1', m, n, c, m, rwork )
281 CALL slacpy(
'Full', m, n, c, m, cf, m )
282
283
284
285 srnamt = 'SGEMQRT'
286 CALL sgemqrt(
'L',
'N', m, n, k, nb2_ub, af, m, t2, nb2, cf, m,
287 $ work, info )
288
289
290
291
292 CALL sgemm(
'N',
'N', m, n, m, -one, q, m, c, m, one, cf, m )
293 resid =
slange(
'1', m, n, cf, m, rwork )
294 IF( cnorm.GT.zero ) THEN
295 result( 3 ) = resid / ( eps * max( 1, m ) * cnorm )
296 ELSE
297 result( 3 ) = zero
298 END IF
299
300
301
302 CALL slacpy(
'Full', m, n, c, m, cf, m )
303
304
305
306 srnamt = 'SGEMQRT'
307 CALL sgemqrt(
'L',
'T', m, n, k, nb2_ub, af, m, t2, nb2, cf, m,
308 $ work, info )
309
310
311
312
313 CALL sgemm(
'T',
'N', m, n, m, -one, q, m, c, m, one, cf, m )
314 resid =
slange(
'1', m, n, cf, m, rwork )
315 IF( cnorm.GT.zero ) THEN
316 result( 4 ) = resid / ( eps * max( 1, m ) * cnorm )
317 ELSE
318 result( 4 ) = zero
319 END IF
320
321
322
323 DO j = 1, m
324 CALL slarnv( 2, iseed, n, d( 1, j ) )
325 END DO
326 dnorm =
slange(
'1', n, m, d, n, rwork )
327 CALL slacpy(
'Full', n, m, d, n, df, n )
328
329
330
331 srnamt = 'SGEMQRT'
332 CALL sgemqrt(
'R',
'N', n, m, k, nb2_ub, af, m, t2, nb2, df, n,
333 $ work, info )
334
335
336
337
338 CALL sgemm(
'N',
'N', n, m, m, -one, d, n, q, m, one, df, n )
339 resid =
slange(
'1', n, m, df, n, rwork )
340 IF( dnorm.GT.zero ) THEN
341 result( 5 ) = resid / ( eps * max( 1, m ) * dnorm )
342 ELSE
343 result( 5 ) = zero
344 END IF
345
346
347
348 CALL slacpy(
'Full', n, m, d, n, df, n )
349
350
351
352 srnamt = 'SGEMQRT'
353 CALL sgemqrt(
'R',
'T', n, m, k, nb2_ub, af, m, t2, nb2, df, n,
354 $ work, info )
355
356
357
358
359 CALL sgemm(
'N',
'T', n, m, m, -one, d, n, q, m, one, df, n )
360 resid =
slange(
'1', n, m, df, n, rwork )
361 IF( dnorm.GT.zero ) THEN
362 result( 6 ) = resid / ( eps * max( 1, m ) * dnorm )
363 ELSE
364 result( 6 ) = zero
365 END IF
366
367
368
369 DEALLOCATE ( a, af, q, r, rwork, work, t1, t2, diag,
370 $ c, d, cf, df )
371
372 RETURN
373
374
375
subroutine sgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
SGEMM
subroutine sgemqrt(side, trans, m, n, k, nb, v, ldv, t, ldt, c, ldc, work, info)
SGEMQRT
subroutine sgetsqrhrt(m, n, mb1, nb1, nb2, a, lda, t, ldt, work, lwork, info)
SGETSQRHRT
subroutine ssyrk(uplo, trans, n, k, alpha, a, lda, beta, c, ldc)
SSYRK
subroutine slacpy(uplo, m, n, a, lda, b, ldb)
SLACPY copies all or part of one two-dimensional array to another.
real function slamch(cmach)
SLAMCH
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 ...
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 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 sscal(n, sa, sx, incx)
SSCAL