Annotation of rpl/lapack/lapack/dptrfs.f, revision 1.4

1.1       bertrand    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>