119 IMPLICIT NONE
120
121
122
123
124
125
126 INTEGER M, N, MB1, NB1, NB2
127
128 REAL RESULT(6)
129
130
131
132
133
134 COMPLEX , ALLOCATABLE :: A(:,:), AF(:,:), Q(:,:), R(:,:),
135 $ WORK( : ), T1(:,:), T2(:,:), DIAG(:),
136 $ C(:,:), CF(:,:), D(:,:), DF(:,:)
137 REAL , ALLOCATABLE :: RWORK(:)
138
139
140 REAL ZERO
141 parameter( zero = 0.0e+0 )
142 COMPLEX CONE, CZERO
143 parameter( cone = ( 1.0e+0, 0.0e+0 ),
144 $ czero = ( 0.0e+0, 0.0e+0 ) )
145
146
147 LOGICAL TESTZEROS
148 INTEGER INFO, I, J, K, L, LWORK, NB1_UB, NB2_UB, NRB
149 REAL ANORM, EPS, RESID, CNORM, DNORM
150
151
152 INTEGER ISEED( 4 )
153 COMPLEX WORKQUERY( 1 )
154
155
156 REAL SLAMCH, CLANGE, CLANSY
158
159
162
163
164 INTRINSIC ceiling, real, max, min
165
166
167 CHARACTER(LEN=32) SRNAMT
168
169
170 COMMON / srmnamc / srnamt
171
172
173 DATA iseed / 1988, 1989, 1990, 1991 /
174
175
176
177 testzeros = .false.
178
180 k = min( m, n )
181 l = max( m, n, 1)
182
183
184
185 ALLOCATE ( a(m,n), af(m,n), q(l,l), r(m,l), rwork(l),
186 $ c(m,n), cf(m,n),
187 $ d(n,m), df(n,m) )
188
189
190
191 DO j = 1, n
192 CALL clarnv( 2, iseed, m, a( 1, j ) )
193 END DO
194 IF( testzeros ) THEN
195 IF( m.GE.4 ) THEN
196 DO j = 1, n
197 CALL clarnv( 2, iseed, m/2, a( m/4, j ) )
198 END DO
199 END IF
200 END IF
201 CALL clacpy(
'Full', m, n, a, m, af, m )
202
203
204
205 nrb = max( 1, ceiling( real( m - n ) / real( mb1 - n ) ) )
206
207 ALLOCATE ( t1( nb1, n * nrb ) )
208 ALLOCATE ( t2( nb2, n ) )
209 ALLOCATE ( diag( n ) )
210
211
212
213
214
215 nb1_ub = min( nb1, n)
216
217
218
219 nb2_ub = min( nb2, n)
220
221 CALL clatsqr( m, n, mb1, nb1_ub, af, m, t1, nb1,
222 $ workquery, -1, info )
223 lwork = int( workquery( 1 ) )
224 CALL cungtsqr( m, n, mb1, nb1, af, m, t1, nb1, workquery, -1,
225 $ info )
226
227 lwork = max( lwork, int( workquery( 1 ) ) )
228
229
230
231
232 lwork = max( lwork, nb2_ub * n, nb2_ub * m )
233
234 ALLOCATE ( work( lwork ) )
235
236
237
238
239
240
241
242
243 srnamt = 'CLATSQR'
244 CALL clatsqr( m, n, mb1, nb1_ub, af, m, t1, nb1, work, lwork,
245 $ info )
246
247
248
249 srnamt = 'CLACPY'
250 CALL clacpy(
'U', n, n, af, m, r, m )
251
252
253
254 srnamt = 'CUNGTSQR'
255 CALL cungtsqr( m, n, mb1, nb1, af, m, t1, nb1, work, lwork,
256 $ info )
257
258
259
260
261 srnamt = 'CUNHR_COL'
262 CALL cunhr_col( m, n, nb2, af, m, t2, nb2, diag, info )
263
264
265
266
267
268
269
270
271 srnamt = 'CLACPY'
272 CALL clacpy(
'U', n, n, r, m, af, m )
273
274 DO i = 1, n
275 IF( diag( i ).EQ.-cone ) THEN
276 CALL cscal( n+1-i, -cone, af( i, i ), m )
277 END IF
278 END DO
279
280
281
282
283
284
285 CALL claset(
'Full', m, m, czero, cone, q, m )
286
287 srnamt = 'CGEMQRT'
288 CALL cgemqrt(
'L',
'N', m, m, k, nb2_ub, af, m, t2, nb2, q, m,
289 $ work, info )
290
291
292
293 CALL claset(
'Full', m, n, czero, czero, r, m )
294
295 CALL clacpy(
'Upper', m, n, af, m, r, m )
296
297
298
299
300 CALL cgemm(
'C',
'N', m, n, m, -cone, q, m, a, m, cone, r, m )
301
302 anorm =
clange(
'1', m, n, a, m, rwork )
303 resid =
clange(
'1', m, n, r, m, rwork )
304 IF( anorm.GT.zero ) THEN
305 result( 1 ) = resid / ( eps * max( 1, m ) * anorm )
306 ELSE
307 result( 1 ) = zero
308 END IF
309
310
311
312
313 CALL claset(
'Full', m, m, czero, cone, r, m )
314 CALL cherk(
'U',
'C', m, m, real(-cone), q, m, real(cone), r, m )
315 resid =
clansy(
'1',
'Upper', m, r, m, rwork )
316 result( 2 ) = resid / ( eps * max( 1, m ) )
317
318
319
320 DO j = 1, n
321 CALL clarnv( 2, iseed, m, c( 1, j ) )
322 END DO
323 cnorm =
clange(
'1', m, n, c, m, rwork )
324 CALL clacpy(
'Full', m, n, c, m, cf, m )
325
326
327
328 srnamt = 'CGEMQRT'
329 CALL cgemqrt(
'L',
'N', m, n, k, nb2_ub, af, m, t2, nb2, cf, m,
330 $ work, info )
331
332
333
334
335 CALL cgemm(
'N',
'N', m, n, m, -cone, q, m, c, m, cone, cf, m )
336 resid =
clange(
'1', m, n, cf, m, rwork )
337 IF( cnorm.GT.zero ) THEN
338 result( 3 ) = resid / ( eps * max( 1, m ) * cnorm )
339 ELSE
340 result( 3 ) = zero
341 END IF
342
343
344
345 CALL clacpy(
'Full', m, n, c, m, cf, m )
346
347
348
349 srnamt = 'CGEMQRT'
350 CALL cgemqrt(
'L',
'C', m, n, k, nb2_ub, af, m, t2, nb2, cf, m,
351 $ work, info )
352
353
354
355
356 CALL cgemm(
'C',
'N', m, n, m, -cone, q, m, c, m, cone, cf, m )
357 resid =
clange(
'1', m, n, cf, m, rwork )
358 IF( cnorm.GT.zero ) THEN
359 result( 4 ) = resid / ( eps * max( 1, m ) * cnorm )
360 ELSE
361 result( 4 ) = zero
362 END IF
363
364
365
366 DO j = 1, m
367 CALL clarnv( 2, iseed, n, d( 1, j ) )
368 END DO
369 dnorm =
clange(
'1', n, m, d, n, rwork )
370 CALL clacpy(
'Full', n, m, d, n, df, n )
371
372
373
374 srnamt = 'CGEMQRT'
375 CALL cgemqrt(
'R',
'N', n, m, k, nb2_ub, af, m, t2, nb2, df, n,
376 $ work, info )
377
378
379
380
381 CALL cgemm(
'N',
'N', n, m, m, -cone, d, n, q, m, cone, df, n )
382 resid =
clange(
'1', n, m, df, n, rwork )
383 IF( dnorm.GT.zero ) THEN
384 result( 5 ) = resid / ( eps * max( 1, m ) * dnorm )
385 ELSE
386 result( 5 ) = zero
387 END IF
388
389
390
391 CALL clacpy(
'Full', n, m, d, n, df, n )
392
393
394
395 srnamt = 'CGEMQRT'
396 CALL cgemqrt(
'R',
'C', n, m, k, nb2_ub, af, m, t2, nb2, df, n,
397 $ work, info )
398
399
400
401
402 CALL cgemm(
'N',
'C', n, m, m, -cone, d, n, q, m, cone, df, n )
403 resid =
clange(
'1', n, m, df, n, rwork )
404 IF( dnorm.GT.zero ) THEN
405 result( 6 ) = resid / ( eps * max( 1, m ) * dnorm )
406 ELSE
407 result( 6 ) = zero
408 END IF
409
410
411
412 DEALLOCATE ( a, af, q, r, rwork, work, t1, t2, diag,
413 $ c, d, cf, df )
414
415 RETURN
416
417
418
subroutine cgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
CGEMM
subroutine cgemqrt(side, trans, m, n, k, nb, v, ldv, t, ldt, c, ldc, work, info)
CGEMQRT
subroutine cherk(uplo, trans, n, k, alpha, a, lda, beta, c, ldc)
CHERK
subroutine clacpy(uplo, m, n, a, lda, b, ldb)
CLACPY copies all or part of one two-dimensional array to another.
real function slamch(cmach)
SLAMCH
real function clange(norm, m, n, a, lda, work)
CLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
real function clansy(norm, uplo, n, a, lda, work)
CLANSY returns the value of the 1-norm, or the Frobenius norm, or the infinity norm,...
subroutine clarnv(idist, iseed, n, x)
CLARNV returns a vector of random numbers from a uniform or normal distribution.
subroutine claset(uplo, m, n, alpha, beta, a, lda)
CLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine clatsqr(m, n, mb, nb, a, lda, t, ldt, work, lwork, info)
CLATSQR
subroutine cscal(n, ca, cx, incx)
CSCAL
subroutine cungtsqr(m, n, mb, nb, a, lda, t, ldt, work, lwork, info)
CUNGTSQR
subroutine cunhr_col(m, n, nb, a, lda, t, ldt, d, info)
CUNHR_COL