LAPACK 3.3.0

ctrrfs.f

Go to the documentation of this file.
00001       SUBROUTINE CTRRFS( UPLO, TRANS, DIAG, N, NRHS, A, LDA, B, LDB, X,
00002      $                   LDX, FERR, BERR, WORK, RWORK, INFO )
00003 *
00004 *  -- LAPACK routine (version 3.2) --
00005 *  -- LAPACK is a software package provided by Univ. of Tennessee,    --
00006 *  -- Univ. of California Berkeley, Univ. of Colorado Denver and NAG Ltd..--
00007 *     November 2006
00008 *
00009 *     Modified to call CLACN2 in place of CLACON, 10 Feb 03, SJH.
00010 *
00011 *     .. Scalar Arguments ..
00012       CHARACTER          DIAG, TRANS, UPLO
00013       INTEGER            INFO, LDA, LDB, LDX, N, NRHS
00014 *     ..
00015 *     .. Array Arguments ..
00016       REAL               BERR( * ), FERR( * ), RWORK( * )
00017       COMPLEX            A( LDA, * ), B( LDB, * ), WORK( * ),
00018      $                   X( LDX, * )
00019 *     ..
00020 *
00021 *  Purpose
00022 *  =======
00023 *
00024 *  CTRRFS provides error bounds and backward error estimates for the
00025 *  solution to a system of linear equations with a triangular
00026 *  coefficient matrix.
00027 *
00028 *  The solution matrix X must be computed by CTRTRS or some other
00029 *  means before entering this routine.  CTRRFS does not do iterative
00030 *  refinement because doing so cannot improve the backward error.
00031 *
00032 *  Arguments
00033 *  =========
00034 *
00035 *  UPLO    (input) CHARACTER*1
00036 *          = 'U':  A is upper triangular;
00037 *          = 'L':  A is lower triangular.
00038 *
00039 *  TRANS   (input) CHARACTER*1
00040 *          Specifies the form of the system of equations:
00041 *          = 'N':  A * X = B     (No transpose)
00042 *          = 'T':  A**T * X = B  (Transpose)
00043 *          = 'C':  A**H * X = B  (Conjugate transpose)
00044 *
00045 *  DIAG    (input) CHARACTER*1
00046 *          = 'N':  A is non-unit triangular;
00047 *          = 'U':  A is unit triangular.
00048 *
00049 *  N       (input) INTEGER
00050 *          The order of the matrix A.  N >= 0.
00051 *
00052 *  NRHS    (input) INTEGER
00053 *          The number of right hand sides, i.e., the number of columns
00054 *          of the matrices B and X.  NRHS >= 0.
00055 *
00056 *  A       (input) COMPLEX array, dimension (LDA,N)
00057 *          The triangular matrix A.  If UPLO = 'U', the leading N-by-N
00058 *          upper triangular part of the array A contains the upper
00059 *          triangular matrix, and the strictly lower triangular part of
00060 *          A is not referenced.  If UPLO = 'L', the leading N-by-N lower
00061 *          triangular part of the array A contains the lower triangular
00062 *          matrix, and the strictly upper triangular part of A is not
00063 *          referenced.  If DIAG = 'U', the diagonal elements of A are
00064 *          also not referenced and are assumed to be 1.
00065 *
00066 *  LDA     (input) INTEGER
00067 *          The leading dimension of the array A.  LDA >= max(1,N).
00068 *
00069 *  B       (input) COMPLEX array, dimension (LDB,NRHS)
00070 *          The right hand side matrix B.
00071 *
00072 *  LDB     (input) INTEGER
00073 *          The leading dimension of the array B.  LDB >= max(1,N).
00074 *
00075 *  X       (input) COMPLEX array, dimension (LDX,NRHS)
00076 *          The solution matrix X.
00077 *
00078 *  LDX     (input) INTEGER
00079 *          The leading dimension of the array X.  LDX >= max(1,N).
00080 *
00081 *  FERR    (output) REAL array, dimension (NRHS)
00082 *          The estimated forward error bound for each solution vector
00083 *          X(j) (the j-th column of the solution matrix X).
00084 *          If XTRUE is the true solution corresponding to X(j), FERR(j)
00085 *          is an estimated upper bound for the magnitude of the largest
00086 *          element in (X(j) - XTRUE) divided by the magnitude of the
00087 *          largest element in X(j).  The estimate is as reliable as
00088 *          the estimate for RCOND, and is almost always a slight
00089 *          overestimate of the true error.
00090 *
00091 *  BERR    (output) REAL array, dimension (NRHS)
00092 *          The componentwise relative backward error of each solution
00093 *          vector X(j) (i.e., the smallest relative change in
00094 *          any element of A or B that makes X(j) an exact solution).
00095 *
00096 *  WORK    (workspace) COMPLEX array, dimension (2*N)
00097 *
00098 *  RWORK   (workspace) REAL array, dimension (N)
00099 *
00100 *  INFO    (output) INTEGER
00101 *          = 0:  successful exit
00102 *          < 0:  if INFO = -i, the i-th argument had an illegal value
00103 *
00104 *  =====================================================================
00105 *
00106 *     .. Parameters ..
00107       REAL               ZERO
00108       PARAMETER          ( ZERO = 0.0E+0 )
00109       COMPLEX            ONE
00110       PARAMETER          ( ONE = ( 1.0E+0, 0.0E+0 ) )
00111 *     ..
00112 *     .. Local Scalars ..
00113       LOGICAL            NOTRAN, NOUNIT, UPPER
00114       CHARACTER          TRANSN, TRANST
00115       INTEGER            I, J, K, KASE, NZ
00116       REAL               EPS, LSTRES, S, SAFE1, SAFE2, SAFMIN, XK
00117       COMPLEX            ZDUM
00118 *     ..
00119 *     .. Local Arrays ..
00120       INTEGER            ISAVE( 3 )
00121 *     ..
00122 *     .. External Subroutines ..
00123       EXTERNAL           CAXPY, CCOPY, CLACN2, CTRMV, CTRSV, XERBLA
00124 *     ..
00125 *     .. Intrinsic Functions ..
00126       INTRINSIC          ABS, AIMAG, MAX, REAL
00127 *     ..
00128 *     .. External Functions ..
00129       LOGICAL            LSAME
00130       REAL               SLAMCH
00131       EXTERNAL           LSAME, SLAMCH
00132 *     ..
00133 *     .. Statement Functions ..
00134       REAL               CABS1
00135 *     ..
00136 *     .. Statement Function definitions ..
00137       CABS1( ZDUM ) = ABS( REAL( ZDUM ) ) + ABS( AIMAG( ZDUM ) )
00138 *     ..
00139 *     .. Executable Statements ..
00140 *
00141 *     Test the input parameters.
00142 *
00143       INFO = 0
00144       UPPER = LSAME( UPLO, 'U' )
00145       NOTRAN = LSAME( TRANS, 'N' )
00146       NOUNIT = LSAME( DIAG, 'N' )
00147 *
00148       IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
00149          INFO = -1
00150       ELSE IF( .NOT.NOTRAN .AND. .NOT.LSAME( TRANS, 'T' ) .AND. .NOT.
00151      $         LSAME( TRANS, 'C' ) ) THEN
00152          INFO = -2
00153       ELSE IF( .NOT.NOUNIT .AND. .NOT.LSAME( DIAG, 'U' ) ) THEN
00154          INFO = -3
00155       ELSE IF( N.LT.0 ) THEN
00156          INFO = -4
00157       ELSE IF( NRHS.LT.0 ) THEN
00158          INFO = -5
00159       ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
00160          INFO = -7
00161       ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
00162          INFO = -9
00163       ELSE IF( LDX.LT.MAX( 1, N ) ) THEN
00164          INFO = -11
00165       END IF
00166       IF( INFO.NE.0 ) THEN
00167          CALL XERBLA( 'CTRRFS', -INFO )
00168          RETURN
00169       END IF
00170 *
00171 *     Quick return if possible
00172 *
00173       IF( N.EQ.0 .OR. NRHS.EQ.0 ) THEN
00174          DO 10 J = 1, NRHS
00175             FERR( J ) = ZERO
00176             BERR( J ) = ZERO
00177    10    CONTINUE
00178          RETURN
00179       END IF
00180 *
00181       IF( NOTRAN ) THEN
00182          TRANSN = 'N'
00183          TRANST = 'C'
00184       ELSE
00185          TRANSN = 'C'
00186          TRANST = 'N'
00187       END IF
00188 *
00189 *     NZ = maximum number of nonzero elements in each row of A, plus 1
00190 *
00191       NZ = N + 1
00192       EPS = SLAMCH( 'Epsilon' )
00193       SAFMIN = SLAMCH( 'Safe minimum' )
00194       SAFE1 = NZ*SAFMIN
00195       SAFE2 = SAFE1 / EPS
00196 *
00197 *     Do for each right hand side
00198 *
00199       DO 250 J = 1, NRHS
00200 *
00201 *        Compute residual R = B - op(A) * X,
00202 *        where op(A) = A, A**T, or A**H, depending on TRANS.
00203 *
00204          CALL CCOPY( N, X( 1, J ), 1, WORK, 1 )
00205          CALL CTRMV( UPLO, TRANS, DIAG, N, A, LDA, WORK, 1 )
00206          CALL CAXPY( N, -ONE, B( 1, J ), 1, WORK, 1 )
00207 *
00208 *        Compute componentwise relative backward error from formula
00209 *
00210 *        max(i) ( abs(R(i)) / ( abs(op(A))*abs(X) + abs(B) )(i) )
00211 *
00212 *        where abs(Z) is the componentwise absolute value of the matrix
00213 *        or vector Z.  If the i-th component of the denominator is less
00214 *        than SAFE2, then SAFE1 is added to the i-th components of the
00215 *        numerator and denominator before dividing.
00216 *
00217          DO 20 I = 1, N
00218             RWORK( I ) = CABS1( B( I, J ) )
00219    20    CONTINUE
00220 *
00221          IF( NOTRAN ) THEN
00222 *
00223 *           Compute abs(A)*abs(X) + abs(B).
00224 *
00225             IF( UPPER ) THEN
00226                IF( NOUNIT ) THEN
00227                   DO 40 K = 1, N
00228                      XK = CABS1( X( K, J ) )
00229                      DO 30 I = 1, K
00230                         RWORK( I ) = RWORK( I ) + CABS1( A( I, K ) )*XK
00231    30                CONTINUE
00232    40             CONTINUE
00233                ELSE
00234                   DO 60 K = 1, N
00235                      XK = CABS1( X( K, J ) )
00236                      DO 50 I = 1, K - 1
00237                         RWORK( I ) = RWORK( I ) + CABS1( A( I, K ) )*XK
00238    50                CONTINUE
00239                      RWORK( K ) = RWORK( K ) + XK
00240    60             CONTINUE
00241                END IF
00242             ELSE
00243                IF( NOUNIT ) THEN
00244                   DO 80 K = 1, N
00245                      XK = CABS1( X( K, J ) )
00246                      DO 70 I = K, N
00247                         RWORK( I ) = RWORK( I ) + CABS1( A( I, K ) )*XK
00248    70                CONTINUE
00249    80             CONTINUE
00250                ELSE
00251                   DO 100 K = 1, N
00252                      XK = CABS1( X( K, J ) )
00253                      DO 90 I = K + 1, N
00254                         RWORK( I ) = RWORK( I ) + CABS1( A( I, K ) )*XK
00255    90                CONTINUE
00256                      RWORK( K ) = RWORK( K ) + XK
00257   100             CONTINUE
00258                END IF
00259             END IF
00260          ELSE
00261 *
00262 *           Compute abs(A**H)*abs(X) + abs(B).
00263 *
00264             IF( UPPER ) THEN
00265                IF( NOUNIT ) THEN
00266                   DO 120 K = 1, N
00267                      S = ZERO
00268                      DO 110 I = 1, K
00269                         S = S + CABS1( A( I, K ) )*CABS1( X( I, J ) )
00270   110                CONTINUE
00271                      RWORK( K ) = RWORK( K ) + S
00272   120             CONTINUE
00273                ELSE
00274                   DO 140 K = 1, N
00275                      S = CABS1( X( K, J ) )
00276                      DO 130 I = 1, K - 1
00277                         S = S + CABS1( A( I, K ) )*CABS1( X( I, J ) )
00278   130                CONTINUE
00279                      RWORK( K ) = RWORK( K ) + S
00280   140             CONTINUE
00281                END IF
00282             ELSE
00283                IF( NOUNIT ) THEN
00284                   DO 160 K = 1, N
00285                      S = ZERO
00286                      DO 150 I = K, N
00287                         S = S + CABS1( A( I, K ) )*CABS1( X( I, J ) )
00288   150                CONTINUE
00289                      RWORK( K ) = RWORK( K ) + S
00290   160             CONTINUE
00291                ELSE
00292                   DO 180 K = 1, N
00293                      S = CABS1( X( K, J ) )
00294                      DO 170 I = K + 1, N
00295                         S = S + CABS1( A( I, K ) )*CABS1( X( I, J ) )
00296   170                CONTINUE
00297                      RWORK( K ) = RWORK( K ) + S
00298   180             CONTINUE
00299                END IF
00300             END IF
00301          END IF
00302          S = ZERO
00303          DO 190 I = 1, N
00304             IF( RWORK( I ).GT.SAFE2 ) THEN
00305                S = MAX( S, CABS1( WORK( I ) ) / RWORK( I ) )
00306             ELSE
00307                S = MAX( S, ( CABS1( WORK( I ) )+SAFE1 ) /
00308      $             ( RWORK( I )+SAFE1 ) )
00309             END IF
00310   190    CONTINUE
00311          BERR( J ) = S
00312 *
00313 *        Bound error from formula
00314 *
00315 *        norm(X - XTRUE) / norm(X) .le. FERR =
00316 *        norm( abs(inv(op(A)))*
00317 *           ( abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) / norm(X)
00318 *
00319 *        where
00320 *          norm(Z) is the magnitude of the largest component of Z
00321 *          inv(op(A)) is the inverse of op(A)
00322 *          abs(Z) is the componentwise absolute value of the matrix or
00323 *             vector Z
00324 *          NZ is the maximum number of nonzeros in any row of A, plus 1
00325 *          EPS is machine epsilon
00326 *
00327 *        The i-th component of abs(R)+NZ*EPS*(abs(op(A))*abs(X)+abs(B))
00328 *        is incremented by SAFE1 if the i-th component of
00329 *        abs(op(A))*abs(X) + abs(B) is less than SAFE2.
00330 *
00331 *        Use CLACN2 to estimate the infinity-norm of the matrix
00332 *           inv(op(A)) * diag(W),
00333 *        where W = abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) )))
00334 *
00335          DO 200 I = 1, N
00336             IF( RWORK( I ).GT.SAFE2 ) THEN
00337                RWORK( I ) = CABS1( WORK( I ) ) + NZ*EPS*RWORK( I )
00338             ELSE
00339                RWORK( I ) = CABS1( WORK( I ) ) + NZ*EPS*RWORK( I ) +
00340      $                      SAFE1
00341             END IF
00342   200    CONTINUE
00343 *
00344          KASE = 0
00345   210    CONTINUE
00346          CALL CLACN2( N, WORK( N+1 ), WORK, FERR( J ), KASE, ISAVE )
00347          IF( KASE.NE.0 ) THEN
00348             IF( KASE.EQ.1 ) THEN
00349 *
00350 *              Multiply by diag(W)*inv(op(A)**H).
00351 *
00352                CALL CTRSV( UPLO, TRANST, DIAG, N, A, LDA, WORK, 1 )
00353                DO 220 I = 1, N
00354                   WORK( I ) = RWORK( I )*WORK( I )
00355   220          CONTINUE
00356             ELSE
00357 *
00358 *              Multiply by inv(op(A))*diag(W).
00359 *
00360                DO 230 I = 1, N
00361                   WORK( I ) = RWORK( I )*WORK( I )
00362   230          CONTINUE
00363                CALL CTRSV( UPLO, TRANSN, DIAG, N, A, LDA, WORK, 1 )
00364             END IF
00365             GO TO 210
00366          END IF
00367 *
00368 *        Normalize error.
00369 *
00370          LSTRES = ZERO
00371          DO 240 I = 1, N
00372             LSTRES = MAX( LSTRES, CABS1( X( I, J ) ) )
00373   240    CONTINUE
00374          IF( LSTRES.NE.ZERO )
00375      $      FERR( J ) = FERR( J ) / LSTRES
00376 *
00377   250 CONTINUE
00378 *
00379       RETURN
00380 *
00381 *     End of CTRRFS
00382 *
00383       END
 All Files Functions