120 IMPLICIT NONE
121
122
123
124
125
126
127 INTEGER M, N, MB1, NB1, NB2
128
129 DOUBLE PRECISION RESULT(6)
130
131
132
133
134
135 COMPLEX*16 , ALLOCATABLE :: A(:,:), AF(:,:), Q(:,:), R(:,:),
136 $ WORK( : ), T1(:,:), T2(:,:), DIAG(:),
137 $ C(:,:), CF(:,:), D(:,:), DF(:,:)
138 DOUBLE PRECISION, ALLOCATABLE :: RWORK(:)
139
140
141 DOUBLE PRECISION ZERO
142 parameter( zero = 0.0d+0 )
143 COMPLEX*16 CONE, CZERO
144 parameter( cone = ( 1.0d+0, 0.0d+0 ),
145 $ czero = ( 0.0d+0, 0.0d+0 ) )
146
147
148 LOGICAL TESTZEROS
149 INTEGER INFO, J, K, L, LWORK, NB2_UB, NRB
150 DOUBLE PRECISION ANORM, EPS, RESID, CNORM, DNORM
151
152
153 INTEGER ISEED( 4 )
154 COMPLEX*16 WORKQUERY( 1 )
155
156
157 DOUBLE PRECISION DLAMCH, ZLANGE, ZLANSY
159
160
163
164
165 INTRINSIC ceiling, dble, 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 zlarnv( 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 zlarnv( 2, iseed, m/2, a( m/4, j ) )
199 END DO
200 END IF
201 END IF
202 CALL zlacpy(
'Full', m, n, a, m, af, m )
203
204
205
206 nrb = max( 1, ceiling( dble( m - n ) / dble( 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 zgetsqrhrt( 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 = 'ZGETSQRHRT'
239 CALL zgetsqrhrt( m, n, mb1, nb1, nb2, af, m, t2, nb2,
240 $ work, lwork, info )
241
242
243
244
245
246
247 CALL zlaset(
'Full', m, m, czero, cone, q, m )
248
249 srnamt = 'ZGEMQRT'
250 CALL zgemqrt(
'L',
'N', m, m, k, nb2_ub, af, m, t2, nb2, q, m,
251 $ work, info )
252
253
254
255 CALL zlaset(
'Full', m, n, czero, czero, r, m )
256
257 CALL zlacpy(
'Upper', m, n, af, m, r, m )
258
259
260
261
262 CALL zgemm(
'C',
'N', m, n, m, -cone, q, m, a, m, cone, r, m )
263
264 anorm =
zlange(
'1', m, n, a, m, rwork )
265 resid =
zlange(
'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 zlaset(
'Full', m, m, czero, cone, r, m )
276 CALL zherk(
'U',
'C', m, m, real(-cone), q, m, real(cone), r, m )
277 resid =
zlansy(
'1',
'Upper', m, r, m, rwork )
278 result( 2 ) = resid / ( eps * max( 1, m ) )
279
280
281
282 DO j = 1, n
283 CALL zlarnv( 2, iseed, m, c( 1, j ) )
284 END DO
285 cnorm =
zlange(
'1', m, n, c, m, rwork )
286 CALL zlacpy(
'Full', m, n, c, m, cf, m )
287
288
289
290 srnamt = 'ZGEMQRT'
291 CALL zgemqrt(
'L',
'N', m, n, k, nb2_ub, af, m, t2, nb2, cf, m,
292 $ work, info )
293
294
295
296
297 CALL zgemm(
'N',
'N', m, n, m, -cone, q, m, c, m, cone, cf, m )
298 resid =
zlange(
'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 zlacpy(
'Full', m, n, c, m, cf, m )
308
309
310
311 srnamt = 'ZGEMQRT'
312 CALL zgemqrt(
'L',
'C', m, n, k, nb2_ub, af, m, t2, nb2, cf, m,
313 $ work, info )
314
315
316
317
318 CALL zgemm(
'C',
'N', m, n, m, -cone, q, m, c, m, cone, cf, m )
319 resid =
zlange(
'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 zlarnv( 2, iseed, n, d( 1, j ) )
330 END DO
331 dnorm =
zlange(
'1', n, m, d, n, rwork )
332 CALL zlacpy(
'Full', n, m, d, n, df, n )
333
334
335
336 srnamt = 'ZGEMQRT'
337 CALL zgemqrt(
'R',
'N', n, m, k, nb2_ub, af, m, t2, nb2, df, n,
338 $ work, info )
339
340
341
342
343 CALL zgemm(
'N',
'N', n, m, m, -cone, d, n, q, m, cone, df, n )
344 resid =
zlange(
'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 zlacpy(
'Full', n, m, d, n, df, n )
354
355
356
357 srnamt = 'ZGEMQRT'
358 CALL zgemqrt(
'R',
'C', n, m, k, nb2_ub, af, m, t2, nb2, df, n,
359 $ work, info )
360
361
362
363
364 CALL zgemm(
'N',
'C', n, m, m, -cone, d, n, q, m, cone, df, n )
365 resid =
zlange(
'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 zgemm(transa, transb, m, n, k, alpha, a, lda, b, ldb, beta, c, ldc)
ZGEMM
subroutine zgemqrt(side, trans, m, n, k, nb, v, ldv, t, ldt, c, ldc, work, info)
ZGEMQRT
subroutine zgetsqrhrt(m, n, mb1, nb1, nb2, a, lda, t, ldt, work, lwork, info)
ZGETSQRHRT
subroutine zherk(uplo, trans, n, k, alpha, a, lda, beta, c, ldc)
ZHERK
subroutine zlacpy(uplo, m, n, a, lda, b, ldb)
ZLACPY copies all or part of one two-dimensional array to another.
double precision function dlamch(cmach)
DLAMCH
double precision function zlange(norm, m, n, a, lda, work)
ZLANGE returns the value of the 1-norm, Frobenius norm, infinity-norm, or the largest absolute value ...
double precision function zlansy(norm, uplo, n, a, lda, work)
ZLANSY returns the value of the 1-norm, or the Frobenius norm, or the infinity norm,...
subroutine zlarnv(idist, iseed, n, x)
ZLARNV returns a vector of random numbers from a uniform or normal distribution.
subroutine zlaset(uplo, m, n, alpha, beta, a, lda)
ZLASET initializes the off-diagonal elements and the diagonal elements of a matrix to given values.
subroutine zscal(n, za, zx, incx)
ZSCAL