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