96 IMPLICIT NONE
97
98 REAL THRESH
99 CHARACTER*3 PATH
100
101 INTEGER NMAX, NPARAMS, NERRBND, NTESTS, KL, KU
102 parameter(nmax = 6, nparams = 2, nerrbnd = 3,
103 $ ntests = 6)
104
105
106 INTEGER N, NRHS, INFO, I ,J, k, NFAIL, LDA,
107 $ N_AUX_TESTS, LDAB, LDAFB
108 CHARACTER FACT, TRANS, UPLO, EQUED
109 CHARACTER*2 C2
110 CHARACTER(3) NGUAR, CGUAR
111 LOGICAL printed_guide
112 REAL NCOND, CCOND, M, NORMDIF, NORMT, RCOND,
113 $ RNORM, RINORM, SUMR, SUMRI, EPS,
114 $ BERR(NMAX), RPVGRW, ORCOND,
115 $ CWISE_ERR, NWISE_ERR, CWISE_BND, NWISE_BND,
116 $ CWISE_RCOND, NWISE_RCOND,
117 $ CONDTHRESH, ERRTHRESH
118 COMPLEX ZDUM
119
120
121 REAL TSTRAT(NTESTS), RINV(NMAX), PARAMS(NPARAMS),
122 $ S(NMAX), R(NMAX),C(NMAX),RWORK(3*NMAX),
123 $ DIFF(NMAX, NMAX),
124 $ ERRBND_N(NMAX*3), ERRBND_C(NMAX*3)
125 INTEGER IPIV(NMAX)
126 COMPLEX A(NMAX,NMAX),INVHILB(NMAX,NMAX),X(NMAX,NMAX),
127 $ WORK(NMAX*3*5), AF(NMAX, NMAX),B(NMAX, NMAX),
128 $ ACOPY(NMAX, NMAX),
129 $ AB( (NMAX-1)+(NMAX-1)+1, NMAX ),
130 $ ABCOPY( (NMAX-1)+(NMAX-1)+1, NMAX ),
131 $ AFB( 2*(NMAX-1)+(NMAX-1)+1, NMAX )
132
133
134 REAL SLAMCH
135
136
139 LOGICAL LSAMEN
140
141
142 INTRINSIC sqrt, max, abs, real, aimag
143
144
145 REAL CABS1
146
147
148 cabs1( zdum ) = abs( real( zdum ) ) + abs( aimag( zdum ) )
149
150
151 INTEGER NWISE_I, CWISE_I
152 parameter(nwise_i = 1, cwise_i = 1)
153 INTEGER BND_I, COND_I
154 parameter(bnd_i = 2, cond_i = 3)
155
156
157
158 fact = 'E'
159 uplo = 'U'
160 trans = 'N'
161 equed = 'N'
163 nfail = 0
164 n_aux_tests = 0
165 lda = nmax
166 ldab = (nmax-1)+(nmax-1)+1
167 ldafb = 2*(nmax-1)+(nmax-1)+1
168 c2 = path( 2: 3 )
169
170
171
172 printed_guide = .false.
173
174 DO n = 1 , nmax
175 params(1) = -1
176 params(2) = -1
177
178 kl = n-1
179 ku = n-1
180 nrhs = n
181 m = max(sqrt(real(n)), 10.0)
182
183
184
185 CALL clahilb(n, n, a, lda, invhilb, lda, b,
186 $ lda, work, info, path)
187
188
189 CALL clacpy(
'ALL', n, n, a, nmax, acopy, nmax)
190
191
192 DO j = 1, n
193 DO i = 1, kl+ku+1
194 ab( i, j ) = (0.0e+0,0.0e+0)
195 END DO
196 END DO
197 DO j = 1, n
198 DO i = max( 1, j-ku ), min( n, j+kl )
199 ab( ku+1+i-j, j ) = a( i, j )
200 END DO
201 END DO
202
203
204 DO j = 1, n
205 DO i = 1, kl+ku+1
206 abcopy( i, j ) = (0.0e+0,0.0e+0)
207 END DO
208 END DO
209 CALL clacpy(
'ALL', kl+ku+1, n, ab, ldab, abcopy, ldab)
210
211
212 IF (
lsamen( 2, c2,
'SY' ) )
THEN
213 CALL csysvxx(fact, uplo, n, nrhs, acopy, lda, af, lda,
214 $ ipiv, equed, s, b, lda, x, lda, orcond,
215 $ rpvgrw, berr, nerrbnd, errbnd_n, errbnd_c, nparams,
216 $ params, work, rwork, info)
217 ELSE IF (
lsamen( 2, c2,
'PO' ) )
THEN
218 CALL cposvxx(fact, uplo, n, nrhs, acopy, lda, af, lda,
219 $ equed, s, b, lda, x, lda, orcond,
220 $ rpvgrw, berr, nerrbnd, errbnd_n, errbnd_c, nparams,
221 $ params, work, rwork, info)
222 ELSE IF (
lsamen( 2, c2,
'HE' ) )
THEN
223 CALL chesvxx(fact, uplo, n, nrhs, acopy, lda, af, lda,
224 $ ipiv, equed, s, b, lda, x, lda, orcond,
225 $ rpvgrw, berr, nerrbnd, errbnd_n, errbnd_c, nparams,
226 $ params, work, rwork, info)
227 ELSE IF (
lsamen( 2, c2,
'GB' ) )
THEN
228 CALL cgbsvxx(fact, trans, n, kl, ku, nrhs, abcopy,
229 $ ldab, afb, ldafb, ipiv, equed, r, c, b,
230 $ lda, x, lda, orcond, rpvgrw, berr, nerrbnd,
231 $ errbnd_n, errbnd_c, nparams, params, work, rwork,
232 $ info)
233 ELSE
234 CALL cgesvxx(fact, trans, n, nrhs, acopy, lda, af, lda,
235 $ ipiv, equed, r, c, b, lda, x, lda, orcond,
236 $ rpvgrw, berr, nerrbnd, errbnd_n, errbnd_c, nparams,
237 $ params, work, rwork, info)
238 END IF
239
240 n_aux_tests = n_aux_tests + 1
241 IF (orcond .LT. eps) THEN
242
243
244
245
246
247
248 ELSE
249
250
251 IF (info .GT. 0 .AND. info .LE. n+1) THEN
252 nfail = nfail + 1
253 WRITE (*, fmt=8000) c2, n, info, orcond, rcond
254 END IF
255 END IF
256
257
258 DO i = 1,n
259 DO j =1,nrhs
260 diff(i,j) = x(i,j) - invhilb(i,j)
261 END DO
262 END DO
263
264
265 rnorm = 0
266 rinorm = 0
267 IF (
lsamen( 2, c2,
'PO' ) .OR.
lsamen( 2, c2,
'SY' ) .OR.
268 $
lsamen( 2, c2,
'HE' ) )
THEN
269 DO i = 1, n
270 sumr = 0
271 sumri = 0
272 DO j = 1, n
273 sumr = sumr + s(i) * cabs1(a(i,j)) * s(j)
274 sumri = sumri + cabs1(invhilb(i, j)) / (s(j) * s(i))
275 END DO
276 rnorm = max(rnorm,sumr)
277 rinorm = max(rinorm,sumri)
278 END DO
279 ELSE IF (
lsamen( 2, c2,
'GE' ) .OR.
lsamen( 2, c2,
'GB' ) )
280 $ THEN
281 DO i = 1, n
282 sumr = 0
283 sumri = 0
284 DO j = 1, n
285 sumr = sumr + r(i) * cabs1(a(i,j)) * c(j)
286 sumri = sumri + cabs1(invhilb(i, j)) / (r(j) * c(i))
287 END DO
288 rnorm = max(rnorm,sumr)
289 rinorm = max(rinorm,sumri)
290 END DO
291 END IF
292
293 rnorm = rnorm / cabs1(a(1, 1))
294 rcond = 1.0/(rnorm * rinorm)
295
296
297 DO i = 1, n
298 rinv(i) = 0.0
299 END DO
300 DO j = 1, n
301 DO i = 1, n
302 rinv(i) = rinv(i) + cabs1(a(i,j))
303 END DO
304 END DO
305
306
307 rinorm = 0.0
308 DO i = 1, n
309 sumri = 0.0
310 DO j = 1, n
311 sumri = sumri + cabs1(invhilb(i,j) * rinv(j))
312 END DO
313 rinorm = max(rinorm, sumri)
314 END DO
315
316
317
318 ncond = cabs1(a(1,1)) / rinorm
319
320 condthresh = m * eps
321 errthresh = m * eps
322
323 DO k = 1, nrhs
324 normt = 0.0
325 normdif = 0.0
326 cwise_err = 0.0
327 DO i = 1, n
328 normt = max(cabs1(invhilb(i, k)), normt)
329 normdif = max(cabs1(x(i,k) - invhilb(i,k)), normdif)
330 IF (invhilb(i,k) .NE. 0.0) THEN
331 cwise_err = max(cabs1(x(i,k) - invhilb(i,k))
332 $ /cabs1(invhilb(i,k)), cwise_err)
333 ELSE IF (x(i, k) .NE. 0.0) THEN
334 cwise_err =
slamch(
'OVERFLOW')
335 END IF
336 END DO
337 IF (normt .NE. 0.0) THEN
338 nwise_err = normdif / normt
339 ELSE IF (normdif .NE. 0.0) THEN
340 nwise_err =
slamch(
'OVERFLOW')
341 ELSE
342 nwise_err = 0.0
343 ENDIF
344
345 DO i = 1, n
346 rinv(i) = 0.0
347 END DO
348 DO j = 1, n
349 DO i = 1, n
350 rinv(i) = rinv(i) + cabs1(a(i, j) * invhilb(j, k))
351 END DO
352 END DO
353 rinorm = 0.0
354 DO i = 1, n
355 sumri = 0.0
356 DO j = 1, n
357 sumri = sumri
358 $ + cabs1(invhilb(i, j) * rinv(j) / invhilb(i, k))
359 END DO
360 rinorm = max(rinorm, sumri)
361 END DO
362
363
364 ccond = cabs1(a(1,1))/rinorm
365
366
367 nwise_bnd = errbnd_n(k + (bnd_i-1)*nrhs)
368 cwise_bnd = errbnd_c(k + (bnd_i-1)*nrhs)
369 nwise_rcond = errbnd_n(k + (cond_i-1)*nrhs)
370 cwise_rcond = errbnd_c(k + (cond_i-1)*nrhs)
371
372
373
374 IF (ncond .GE. condthresh) THEN
375 nguar = 'YES'
376 IF (nwise_bnd .GT. errthresh) THEN
377 tstrat(1) = 1/(2.0*eps)
378 ELSE
379 IF (nwise_bnd .NE. 0.0) THEN
380 tstrat(1) = nwise_err / nwise_bnd
381 ELSE IF (nwise_err .NE. 0.0) THEN
382 tstrat(1) = 1/(16.0*eps)
383 ELSE
384 tstrat(1) = 0.0
385 END IF
386 IF (tstrat(1) .GT. 1.0) THEN
387 tstrat(1) = 1/(4.0*eps)
388 END IF
389 END IF
390 ELSE
391 nguar = 'NO'
392 IF (nwise_bnd .LT. 1.0) THEN
393 tstrat(1) = 1/(8.0*eps)
394 ELSE
395 tstrat(1) = 1.0
396 END IF
397 END IF
398
399
400
401 IF (ccond .GE. condthresh) THEN
402 cguar = 'YES'
403 IF (cwise_bnd .GT. errthresh) THEN
404 tstrat(2) = 1/(2.0*eps)
405 ELSE
406 IF (cwise_bnd .NE. 0.0) THEN
407 tstrat(2) = cwise_err / cwise_bnd
408 ELSE IF (cwise_err .NE. 0.0) THEN
409 tstrat(2) = 1/(16.0*eps)
410 ELSE
411 tstrat(2) = 0.0
412 END IF
413 IF (tstrat(2) .GT. 1.0) tstrat(2) = 1/(4.0*eps)
414 END IF
415 ELSE
416 cguar = 'NO'
417 IF (cwise_bnd .LT. 1.0) THEN
418 tstrat(2) = 1/(8.0*eps)
419 ELSE
420 tstrat(2) = 1.0
421 END IF
422 END IF
423
424
425 tstrat(3) = berr(k)/eps
426
427
428 tstrat(4) = rcond / orcond
429 IF (rcond .GE. condthresh .AND. tstrat(4) .LT. 1.0)
430 $ tstrat(4) = 1.0 / tstrat(4)
431
432 tstrat(5) = ncond / nwise_rcond
433 IF (ncond .GE. condthresh .AND. tstrat(5) .LT. 1.0)
434 $ tstrat(5) = 1.0 / tstrat(5)
435
436 tstrat(6) = ccond / nwise_rcond
437 IF (ccond .GE. condthresh .AND. tstrat(6) .LT. 1.0)
438 $ tstrat(6) = 1.0 / tstrat(6)
439
440 DO i = 1, ntests
441 IF (tstrat(i) .GT. thresh) THEN
442 IF (.NOT.printed_guide) THEN
443 WRITE(*,*)
444 WRITE( *, 9996) 1
445 WRITE( *, 9995) 2
446 WRITE( *, 9994) 3
447 WRITE( *, 9993) 4
448 WRITE( *, 9992) 5
449 WRITE( *, 9991) 6
450 WRITE( *, 9990) 7
451 WRITE( *, 9989) 8
452 WRITE(*,*)
453 printed_guide = .true.
454 END IF
455 WRITE( *, 9999) c2, n, k, nguar, cguar, i, tstrat(i)
456 nfail = nfail + 1
457 END IF
458 END DO
459 END DO
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475 END DO
476
477 WRITE(*,*)
478 IF( nfail .GT. 0 ) THEN
479 WRITE(*,9998) c2, nfail, ntests*n+n_aux_tests
480 ELSE
481 WRITE(*,9997) c2
482 END IF
483 9999 FORMAT( ' C', a2, 'SVXX: N =', i2, ', RHS = ', i2,
484 $ ', NWISE GUAR. = ', a, ', CWISE GUAR. = ', a,
485 $ ' test(',i1,') =', g12.5 )
486 9998 FORMAT( ' C', a2, 'SVXX: ', i6, ' out of ', i6,
487 $ ' tests failed to pass the threshold' )
488 9997 FORMAT( ' C', a2, 'SVXX passed the tests of error bounds' )
489
490 9996 FORMAT( 3x, i2, ': Normwise guaranteed forward error', / 5x,
491 $ 'Guaranteed case: if norm ( abs( Xc - Xt )',
492 $ .LE.' / norm ( Xt ) ERRBND( *, nwise_i, bnd_i ), then',
493 $ / 5x,
494 $ .LE.'ERRBND( *, nwise_i, bnd_i ) MAX(SQRT(N), 10) * EPS')
495 9995 FORMAT( 3x, i2, ': Componentwise guaranteed forward error' )
496 9994 FORMAT( 3x, i2, ': Backwards error' )
497 9993 FORMAT( 3x, i2, ': Reciprocal condition number' )
498 9992 FORMAT( 3x, i2, ': Reciprocal normwise condition number' )
499 9991 FORMAT( 3x, i2, ': Raw normwise error estimate' )
500 9990 FORMAT( 3x, i2, ': Reciprocal componentwise condition number' )
501 9989 FORMAT( 3x, i2, ': Raw componentwise error estimate' )
502
503 8000 FORMAT( ' C', a2, 'SVXX: N =', i2, ', INFO = ', i3,
504 $ ', ORCOND = ', g12.5, ', real RCOND = ', g12.5 )
505
506
507
subroutine clahilb(n, nrhs, a, lda, x, ldx, b, ldb, work, info, path)
CLAHILB
subroutine cgbsvxx(fact, trans, n, kl, ku, nrhs, ab, ldab, afb, ldafb, ipiv, equed, r, c, b, ldb, x, ldx, rcond, rpvgrw, berr, n_err_bnds, err_bnds_norm, err_bnds_comp, nparams, params, work, rwork, info)
CGBSVXX computes the solution to system of linear equations A * X = B for GB matrices
subroutine cgesvxx(fact, trans, n, nrhs, a, lda, af, ldaf, ipiv, equed, r, c, b, ldb, x, ldx, rcond, rpvgrw, berr, n_err_bnds, err_bnds_norm, err_bnds_comp, nparams, params, work, rwork, info)
CGESVXX computes the solution to system of linear equations A * X = B for GE matrices
subroutine csysvxx(fact, uplo, n, nrhs, a, lda, af, ldaf, ipiv, equed, s, b, ldb, x, ldx, rcond, rpvgrw, berr, n_err_bnds, err_bnds_norm, err_bnds_comp, nparams, params, work, rwork, info)
CSYSVXX computes the solution to system of linear equations A * X = B for SY matrices
subroutine chesvxx(fact, uplo, n, nrhs, a, lda, af, ldaf, ipiv, equed, s, b, ldb, x, ldx, rcond, rpvgrw, berr, n_err_bnds, err_bnds_norm, err_bnds_comp, nparams, params, work, rwork, info)
CHESVXX computes the solution to system of linear equations A * X = B for HE matrices
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
logical function lsamen(n, ca, cb)
LSAMEN
subroutine cposvxx(fact, uplo, n, nrhs, a, lda, af, ldaf, equed, s, b, ldb, x, ldx, rcond, rpvgrw, berr, n_err_bnds, err_bnds_norm, err_bnds_comp, nparams, params, work, rwork, info)
CPOSVXX computes the solution to system of linear equations A * X = B for PO matrices