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