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 COMPLEX , ALLOCATABLE :: A(:,:), AF(:,:), Q(:,:), R(:,:),
136 $ WORK( : ), T1(:,:), T2(:,:), DIAG(:),
137 $ C(:,:), CF(:,:), D(:,:), DF(:,:)
138 REAL , ALLOCATABLE :: RWORK(:)
139
140
141 REAL ZERO
142 parameter( zero = 0.0e+0 )
143 COMPLEX CONE, CZERO
144 parameter( cone = ( 1.0e+0, 0.0e+0 ),
145 $ czero = ( 0.0e+0, 0.0e+0 ) )
146
147
148 LOGICAL TESTZEROS
149 INTEGER INFO, J, K, L, LWORK, NB2_UB, NRB
150 REAL ANORM, EPS, RESID, CNORM, DNORM
151
152
153 INTEGER ISEED( 4 )
154 COMPLEX WORKQUERY( 1 )
155
156
157 REAL SLAMCH, CLANGE, CLANSY
159
160
163
164
165 INTRINSIC ceiling, real, max, min
166
167
168 CHARACTER(LEN=32) SRNAMT
169
170
171 COMMON / srmnamc / srnamt
172
173
174 DATA iseed / 1988, 1989, 1990, 1991 /
175
176
177
178 testzeros = .false.
179
181 k = min( m, n )
182 l = max( m, n, 1)
183
184
185
186 ALLOCATE ( a(m,n), af(m,n), q(l,l), r(m,l), rwork(l),
187 $ c(m,n), cf(m,n),
188 $ d(n,m), df(n,m) )
189
190
191
192 DO j = 1, n
193 CALL clarnv( 2, iseed, m, a( 1, j ) )
194 END DO
195 IF( testzeros ) THEN
196 IF( m.GE.4 ) THEN
197 DO j = 1, n
198 CALL clarnv( 2, iseed, m/2, a( m/4, j ) )
199 END DO
200 END IF
201 END IF
202 CALL clacpy(
'Full', m, n, a, m, af, m )
203
204
205
206 nrb = max( 1, ceiling( real( m - n ) / real( mb1 - n ) ) )
207
208 ALLOCATE ( t1( nb1, n * nrb ) )
209 ALLOCATE ( t2( nb2, n ) )
210 ALLOCATE ( diag( n ) )
211
212
213
214
215
216 nb2_ub = min( nb2, n)
217
218
219 CALL cgetsqrhrt( m, n, mb1, nb1, nb2, af, m, t2, nb2,
220 $ workquery, -1, info )
221
222 lwork = int( workquery( 1 ) )
223
224
225
226
227 lwork = max( lwork, nb2_ub * n, nb2_ub * m )
228
229 ALLOCATE ( work( lwork ) )
230
231
232
233
234
235
236
237
238 srnamt = 'CGETSQRHRT'
239 CALL cgetsqrhrt( m, n, mb1, nb1, nb2, af, m, t2, nb2,
240 $ work, lwork, info )
241
242
243
244
245
246
247 CALL claset(
'Full', m, m, czero, cone, q, m )
248
249 srnamt = 'CGEMQRT'
250 CALL cgemqrt(
'L',
'N', m, m, k, nb2_ub, af, m, t2, nb2, q, m,
251 $ work, info )
252
253
254
255 CALL claset(
'Full', m, n, czero, czero, r, m )
256
257 CALL clacpy(
'Upper', m, n, af, m, r, m )
258
259
260
261
262 CALL cgemm(
'C',
'N', m, n, m, -cone, q, m, a, m, cone, r, m )
263
264 anorm =
clange(
'1', m, n, a, m, rwork )
265 resid =
clange(
'1', m, n, r, m, rwork )
266 IF( anorm.GT.zero ) THEN
267 result( 1 ) = resid / ( eps * max( 1, m ) * anorm )
268 ELSE
269 result( 1 ) = zero
270 END IF
271
272
273
274
275 CALL claset(
'Full', m, m, czero, cone, r, m )
276 CALL cherk(
'U',
'C', m, m, real(-cone), q, m, real(cone), r, m )
277 resid =
clansy(
'1',
'Upper', m, r, m, rwork )
278 result( 2 ) = resid / ( eps * max( 1, m ) )
279
280
281
282 DO j = 1, n
283 CALL clarnv( 2, iseed, m, c( 1, j ) )
284 END DO
285 cnorm =
clange(
'1', m, n, c, m, rwork )
286 CALL clacpy(
'Full', m, n, c, m, cf, m )
287
288
289
290 srnamt = 'CGEMQRT'
291 CALL cgemqrt(
'L',
'N', m, n, k, nb2_ub, af, m, t2, nb2, cf, m,
292 $ work, info )
293
294
295
296
297 CALL cgemm(
'N',
'N', m, n, m, -cone, q, m, c, m, cone, cf, m )
298 resid =
clange(
'1', m, n, cf, m, rwork )
299 IF( cnorm.GT.zero ) THEN
300 result( 3 ) = resid / ( eps * max( 1, m ) * cnorm )
301 ELSE
302 result( 3 ) = zero
303 END IF
304
305
306
307 CALL clacpy(
'Full', m, n, c, m, cf, m )
308
309
310
311 srnamt = 'CGEMQRT'
312 CALL cgemqrt(
'L',
'C', m, n, k, nb2_ub, af, m, t2, nb2, cf, m,
313 $ work, info )
314
315
316
317
318 CALL cgemm(
'C',
'N', m, n, m, -cone, q, m, c, m, cone, cf, m )
319 resid =
clange(
'1', m, n, cf, m, rwork )
320 IF( cnorm.GT.zero ) THEN
321 result( 4 ) = resid / ( eps * max( 1, m ) * cnorm )
322 ELSE
323 result( 4 ) = zero
324 END IF
325
326
327
328 DO j = 1, m
329 CALL clarnv( 2, iseed, n, d( 1, j ) )
330 END DO
331 dnorm =
clange(
'1', n, m, d, n, rwork )
332 CALL clacpy(
'Full', n, m, d, n, df, n )
333
334
335
336 srnamt = 'CGEMQRT'
337 CALL cgemqrt(
'R',
'N', n, m, k, nb2_ub, af, m, t2, nb2, df, n,
338 $ work, info )
339
340
341
342
343 CALL cgemm(
'N',
'N', n, m, m, -cone, d, n, q, m, cone, df, n )
344 resid =
clange(
'1', n, m, df, n, rwork )
345 IF( dnorm.GT.zero ) THEN
346 result( 5 ) = resid / ( eps * max( 1, m ) * dnorm )
347 ELSE
348 result( 5 ) = zero
349 END IF
350
351
352
353 CALL clacpy(
'Full', n, m, d, n, df, n )
354
355
356
357 srnamt = 'CGEMQRT'
358 CALL cgemqrt(
'R',
'C', n, m, k, nb2_ub, af, m, t2, nb2, df, n,
359 $ work, info )
360
361
362
363
364 CALL cgemm(
'N',
'C', n, m, m, -cone, d, n, q, m, cone, df, n )
365 resid =
clange(
'1', n, m, df, n, rwork )
366 IF( dnorm.GT.zero ) THEN
367 result( 6 ) = resid / ( eps * max( 1, m ) * dnorm )
368 ELSE
369 result( 6 ) = zero
370 END IF
371
372
373
374 DEALLOCATE ( a, af, q, r, rwork, work, t1, t2, diag,
375 $ c, d, cf, df )
376
377 RETURN
378
379
380
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 cgetsqrhrt(m, n, mb1, nb1, nb2, a, lda, t, ldt, work, lwork, info)
CGETSQRHRT
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 cscal(n, ca, cx, incx)
CSCAL