File:  [local] / rpl / lapack / lapack / dptrfs.f
Revision 1.5: download - view: text, annotated - select for diffs - revision graph
Sat Aug 7 13:22:24 2010 UTC (13 years, 9 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Mise à jour globale de Lapack 3.2.2.

    1:       SUBROUTINE DPTRFS( N, NRHS, D, E, DF, EF, B, LDB, X, LDX, FERR,
    2:      $                   BERR, WORK, INFO )
    3: *
    4: *  -- LAPACK routine (version 3.2) --
    5: *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
    6: *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
    7: *     November 2006
    8: *
    9: *     .. Scalar Arguments ..
   10:       INTEGER            INFO, LDB, LDX, N, NRHS
   11: *     ..
   12: *     .. Array Arguments ..
   13:       DOUBLE PRECISION   B( LDB, * ), BERR( * ), D( * ), DF( * ),
   14:      $                   E( * ), EF( * ), FERR( * ), WORK( * ),
   15:      $                   X( LDX, * )
   16: *     ..
   17: *
   18: *  Purpose
   19: *  =======
   20: *
   21: *  DPTRFS improves the computed solution to a system of linear
   22: *  equations when the coefficient matrix is symmetric positive definite
   23: *  and tridiagonal, and provides error bounds and backward error
   24: *  estimates for the solution.
   25: *
   26: *  Arguments
   27: *  =========
   28: *
   29: *  N       (input) INTEGER
   30: *          The order of the matrix A.  N >= 0.
   31: *
   32: *  NRHS    (input) INTEGER
   33: *          The number of right hand sides, i.e., the number of columns
   34: *          of the matrix B.  NRHS >= 0.
   35: *
   36: *  D       (input) DOUBLE PRECISION array, dimension (N)
   37: *          The n diagonal elements of the tridiagonal matrix A.
   38: *
   39: *  E       (input) DOUBLE PRECISION array, dimension (N-1)
   40: *          The (n-1) subdiagonal elements of the tridiagonal matrix A.
   41: *
   42: *  DF      (input) DOUBLE PRECISION array, dimension (N)
   43: *          The n diagonal elements of the diagonal matrix D from the
   44: *          factorization computed by DPTTRF.
   45: *
   46: *  EF      (input) DOUBLE PRECISION array, dimension (N-1)
   47: *          The (n-1) subdiagonal elements of the unit bidiagonal factor
   48: *          L from the factorization computed by DPTTRF.
   49: *
   50: *  B       (input) DOUBLE PRECISION array, dimension (LDB,NRHS)
   51: *          The right hand side matrix B.
   52: *
   53: *  LDB     (input) INTEGER
   54: *          The leading dimension of the array B.  LDB >= max(1,N).
   55: *
   56: *  X       (input/output) DOUBLE PRECISION array, dimension (LDX,NRHS)
   57: *          On entry, the solution matrix X, as computed by DPTTRS.
   58: *          On exit, the improved solution matrix X.
   59: *
   60: *  LDX     (input) INTEGER
   61: *          The leading dimension of the array X.  LDX >= max(1,N).
   62: *
   63: *  FERR    (output) DOUBLE PRECISION array, dimension (NRHS)
   64: *          The forward error bound for each solution vector
   65: *          X(j) (the j-th column of the solution matrix X).
   66: *          If XTRUE is the true solution corresponding to X(j), FERR(j)
   67: *          is an estimated upper bound for the magnitude of the largest
   68: *          element in (X(j) - XTRUE) divided by the magnitude of the
   69: *          largest element in X(j).
   70: *
   71: *  BERR    (output) DOUBLE PRECISION array, dimension (NRHS)
   72: *          The componentwise relative backward error of each solution
   73: *          vector X(j) (i.e., the smallest relative change in
   74: *          any element of A or B that makes X(j) an exact solution).
   75: *
   76: *  WORK    (workspace) DOUBLE PRECISION array, dimension (2*N)
   77: *
   78: *  INFO    (output) INTEGER
   79: *          = 0:  successful exit
   80: *          < 0:  if INFO = -i, the i-th argument had an illegal value
   81: *
   82: *  Internal Parameters
   83: *  ===================
   84: *
   85: *  ITMAX is the maximum number of steps of iterative refinement.
   86: *
   87: *  =====================================================================
   88: *
   89: *     .. Parameters ..
   90:       INTEGER            ITMAX
   91:       PARAMETER          ( ITMAX = 5 )
   92:       DOUBLE PRECISION   ZERO
   93:       PARAMETER          ( ZERO = 0.0D+0 )
   94:       DOUBLE PRECISION   ONE
   95:       PARAMETER          ( ONE = 1.0D+0 )
   96:       DOUBLE PRECISION   TWO
   97:       PARAMETER          ( TWO = 2.0D+0 )
   98:       DOUBLE PRECISION   THREE
   99:       PARAMETER          ( THREE = 3.0D+0 )
  100: *     ..
  101: *     .. Local Scalars ..
  102:       INTEGER            COUNT, I, IX, J, NZ
  103:       DOUBLE PRECISION   BI, CX, DX, EPS, EX, LSTRES, S, SAFE1, SAFE2,
  104:      $                   SAFMIN
  105: *     ..
  106: *     .. External Subroutines ..
  107:       EXTERNAL           DAXPY, DPTTRS, XERBLA
  108: *     ..
  109: *     .. Intrinsic Functions ..
  110:       INTRINSIC          ABS, MAX
  111: *     ..
  112: *     .. External Functions ..
  113:       INTEGER            IDAMAX
  114:       DOUBLE PRECISION   DLAMCH
  115:       EXTERNAL           IDAMAX, DLAMCH
  116: *     ..
  117: *     .. Executable Statements ..
  118: *
  119: *     Test the input parameters.
  120: *
  121:       INFO = 0
  122:       IF( N.LT.0 ) THEN
  123:          INFO = -1
  124:       ELSE IF( NRHS.LT.0 ) THEN
  125:          INFO = -2
  126:       ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
  127:          INFO = -8
  128:       ELSE IF( LDX.LT.MAX( 1, N ) ) THEN
  129:          INFO = -10
  130:       END IF
  131:       IF( INFO.NE.0 ) THEN
  132:          CALL XERBLA( 'DPTRFS', -INFO )
  133:          RETURN
  134:       END IF
  135: *
  136: *     Quick return if possible
  137: *
  138:       IF( N.EQ.0 .OR. NRHS.EQ.0 ) THEN
  139:          DO 10 J = 1, NRHS
  140:             FERR( J ) = ZERO
  141:             BERR( J ) = ZERO
  142:    10    CONTINUE
  143:          RETURN
  144:       END IF
  145: *
  146: *     NZ = maximum number of nonzero elements in each row of A, plus 1
  147: *
  148:       NZ = 4
  149:       EPS = DLAMCH( 'Epsilon' )
  150:       SAFMIN = DLAMCH( 'Safe minimum' )
  151:       SAFE1 = NZ*SAFMIN
  152:       SAFE2 = SAFE1 / EPS
  153: *
  154: *     Do for each right hand side
  155: *
  156:       DO 90 J = 1, NRHS
  157: *
  158:          COUNT = 1
  159:          LSTRES = THREE
  160:    20    CONTINUE
  161: *
  162: *        Loop until stopping criterion is satisfied.
  163: *
  164: *        Compute residual R = B - A * X.  Also compute
  165: *        abs(A)*abs(x) + abs(b) for use in the backward error bound.
  166: *
  167:          IF( N.EQ.1 ) THEN
  168:             BI = B( 1, J )
  169:             DX = D( 1 )*X( 1, J )
  170:             WORK( N+1 ) = BI - DX
  171:             WORK( 1 ) = ABS( BI ) + ABS( DX )
  172:          ELSE
  173:             BI = B( 1, J )
  174:             DX = D( 1 )*X( 1, J )
  175:             EX = E( 1 )*X( 2, J )
  176:             WORK( N+1 ) = BI - DX - EX
  177:             WORK( 1 ) = ABS( BI ) + ABS( DX ) + ABS( EX )
  178:             DO 30 I = 2, N - 1
  179:                BI = B( I, J )
  180:                CX = E( I-1 )*X( I-1, J )
  181:                DX = D( I )*X( I, J )
  182:                EX = E( I )*X( I+1, J )
  183:                WORK( N+I ) = BI - CX - DX - EX
  184:                WORK( I ) = ABS( BI ) + ABS( CX ) + ABS( DX ) + ABS( EX )
  185:    30       CONTINUE
  186:             BI = B( N, J )
  187:             CX = E( N-1 )*X( N-1, J )
  188:             DX = D( N )*X( N, J )
  189:             WORK( N+N ) = BI - CX - DX
  190:             WORK( N ) = ABS( BI ) + ABS( CX ) + ABS( DX )
  191:          END IF
  192: *
  193: *        Compute componentwise relative backward error from formula
  194: *
  195: *        max(i) ( abs(R(i)) / ( abs(A)*abs(X) + abs(B) )(i) )
  196: *
  197: *        where abs(Z) is the componentwise absolute value of the matrix
  198: *        or vector Z.  If the i-th component of the denominator is less
  199: *        than SAFE2, then SAFE1 is added to the i-th components of the
  200: *        numerator and denominator before dividing.
  201: *
  202:          S = ZERO
  203:          DO 40 I = 1, N
  204:             IF( WORK( I ).GT.SAFE2 ) THEN
  205:                S = MAX( S, ABS( WORK( N+I ) ) / WORK( I ) )
  206:             ELSE
  207:                S = MAX( S, ( ABS( WORK( N+I ) )+SAFE1 ) /
  208:      $             ( WORK( I )+SAFE1 ) )
  209:             END IF
  210:    40    CONTINUE
  211:          BERR( J ) = S
  212: *
  213: *        Test stopping criterion. Continue iterating if
  214: *           1) The residual BERR(J) is larger than machine epsilon, and
  215: *           2) BERR(J) decreased by at least a factor of 2 during the
  216: *              last iteration, and
  217: *           3) At most ITMAX iterations tried.
  218: *
  219:          IF( BERR( J ).GT.EPS .AND. TWO*BERR( J ).LE.LSTRES .AND.
  220:      $       COUNT.LE.ITMAX ) THEN
  221: *
  222: *           Update solution and try again.
  223: *
  224:             CALL DPTTRS( N, 1, DF, EF, WORK( N+1 ), N, INFO )
  225:             CALL DAXPY( N, ONE, WORK( N+1 ), 1, X( 1, J ), 1 )
  226:             LSTRES = BERR( J )
  227:             COUNT = COUNT + 1
  228:             GO TO 20
  229:          END IF
  230: *
  231: *        Bound error from formula
  232: *
  233: *        norm(X - XTRUE) / norm(X) .le. FERR =
  234: *        norm( abs(inv(A))*
  235: *           ( abs(R) + NZ*EPS*( abs(A)*abs(X)+abs(B) ))) / norm(X)
  236: *
  237: *        where
  238: *          norm(Z) is the magnitude of the largest component of Z
  239: *          inv(A) is the inverse of A
  240: *          abs(Z) is the componentwise absolute value of the matrix or
  241: *             vector Z
  242: *          NZ is the maximum number of nonzeros in any row of A, plus 1
  243: *          EPS is machine epsilon
  244: *
  245: *        The i-th component of abs(R)+NZ*EPS*(abs(A)*abs(X)+abs(B))
  246: *        is incremented by SAFE1 if the i-th component of
  247: *        abs(A)*abs(X) + abs(B) is less than SAFE2.
  248: *
  249:          DO 50 I = 1, N
  250:             IF( WORK( I ).GT.SAFE2 ) THEN
  251:                WORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I )
  252:             ELSE
  253:                WORK( I ) = ABS( WORK( N+I ) ) + NZ*EPS*WORK( I ) + SAFE1
  254:             END IF
  255:    50    CONTINUE
  256:          IX = IDAMAX( N, WORK, 1 )
  257:          FERR( J ) = WORK( IX )
  258: *
  259: *        Estimate the norm of inv(A).
  260: *
  261: *        Solve M(A) * x = e, where M(A) = (m(i,j)) is given by
  262: *
  263: *           m(i,j) =  abs(A(i,j)), i = j,
  264: *           m(i,j) = -abs(A(i,j)), i .ne. j,
  265: *
  266: *        and e = [ 1, 1, ..., 1 ]'.  Note M(A) = M(L)*D*M(L)'.
  267: *
  268: *        Solve M(L) * x = e.
  269: *
  270:          WORK( 1 ) = ONE
  271:          DO 60 I = 2, N
  272:             WORK( I ) = ONE + WORK( I-1 )*ABS( EF( I-1 ) )
  273:    60    CONTINUE
  274: *
  275: *        Solve D * M(L)' * x = b.
  276: *
  277:          WORK( N ) = WORK( N ) / DF( N )
  278:          DO 70 I = N - 1, 1, -1
  279:             WORK( I ) = WORK( I ) / DF( I ) + WORK( I+1 )*ABS( EF( I ) )
  280:    70    CONTINUE
  281: *
  282: *        Compute norm(inv(A)) = max(x(i)), 1<=i<=n.
  283: *
  284:          IX = IDAMAX( N, WORK, 1 )
  285:          FERR( J ) = FERR( J )*ABS( WORK( IX ) )
  286: *
  287: *        Normalize error.
  288: *
  289:          LSTRES = ZERO
  290:          DO 80 I = 1, N
  291:             LSTRES = MAX( LSTRES, ABS( X( I, J ) ) )
  292:    80    CONTINUE
  293:          IF( LSTRES.NE.ZERO )
  294:      $      FERR( J ) = FERR( J ) / LSTRES
  295: *
  296:    90 CONTINUE
  297: *
  298:       RETURN
  299: *
  300: *     End of DPTRFS
  301: *
  302:       END

CVSweb interface <joel.bertrand@systella.fr>