00001 SUBROUTINE CPBRFS( UPLO, N, KD, NRHS, AB, LDAB, AFB, LDAFB, B,
00002 $ LDB, X, LDX, FERR, BERR, WORK, RWORK, INFO )
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 CHARACTER UPLO
00013 INTEGER INFO, KD, LDAB, LDAFB, LDB, LDX, N, NRHS
00014
00015
00016 REAL BERR( * ), FERR( * ), RWORK( * )
00017 COMPLEX AB( LDAB, * ), AFB( LDAFB, * ), B( LDB, * ),
00018 $ WORK( * ), X( LDX, * )
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 INTEGER ITMAX
00110 PARAMETER ( ITMAX = 5 )
00111 REAL ZERO
00112 PARAMETER ( ZERO = 0.0E+0 )
00113 COMPLEX ONE
00114 PARAMETER ( ONE = ( 1.0E+0, 0.0E+0 ) )
00115 REAL TWO
00116 PARAMETER ( TWO = 2.0E+0 )
00117 REAL THREE
00118 PARAMETER ( THREE = 3.0E+0 )
00119
00120
00121 LOGICAL UPPER
00122 INTEGER COUNT, I, J, K, KASE, L, NZ
00123 REAL EPS, LSTRES, S, SAFE1, SAFE2, SAFMIN, XK
00124 COMPLEX ZDUM
00125
00126
00127 INTEGER ISAVE( 3 )
00128
00129
00130 EXTERNAL CAXPY, CCOPY, CHBMV, CLACN2, CPBTRS, XERBLA
00131
00132
00133 INTRINSIC ABS, AIMAG, MAX, MIN, REAL
00134
00135
00136 LOGICAL LSAME
00137 REAL SLAMCH
00138 EXTERNAL LSAME, SLAMCH
00139
00140
00141 REAL CABS1
00142
00143
00144 CABS1( ZDUM ) = ABS( REAL( ZDUM ) ) + ABS( AIMAG( ZDUM ) )
00145
00146
00147
00148
00149
00150 INFO = 0
00151 UPPER = LSAME( UPLO, 'U' )
00152 IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
00153 INFO = -1
00154 ELSE IF( N.LT.0 ) THEN
00155 INFO = -2
00156 ELSE IF( KD.LT.0 ) THEN
00157 INFO = -3
00158 ELSE IF( NRHS.LT.0 ) THEN
00159 INFO = -4
00160 ELSE IF( LDAB.LT.KD+1 ) THEN
00161 INFO = -6
00162 ELSE IF( LDAFB.LT.KD+1 ) THEN
00163 INFO = -8
00164 ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
00165 INFO = -10
00166 ELSE IF( LDX.LT.MAX( 1, N ) ) THEN
00167 INFO = -12
00168 END IF
00169 IF( INFO.NE.0 ) THEN
00170 CALL XERBLA( 'CPBRFS', -INFO )
00171 RETURN
00172 END IF
00173
00174
00175
00176 IF( N.EQ.0 .OR. NRHS.EQ.0 ) THEN
00177 DO 10 J = 1, NRHS
00178 FERR( J ) = ZERO
00179 BERR( J ) = ZERO
00180 10 CONTINUE
00181 RETURN
00182 END IF
00183
00184
00185
00186 NZ = MIN( N+1, 2*KD+2 )
00187 EPS = SLAMCH( 'Epsilon' )
00188 SAFMIN = SLAMCH( 'Safe minimum' )
00189 SAFE1 = NZ*SAFMIN
00190 SAFE2 = SAFE1 / EPS
00191
00192
00193
00194 DO 140 J = 1, NRHS
00195
00196 COUNT = 1
00197 LSTRES = THREE
00198 20 CONTINUE
00199
00200
00201
00202
00203
00204 CALL CCOPY( N, B( 1, J ), 1, WORK, 1 )
00205 CALL CHBMV( UPLO, N, KD, -ONE, AB, LDAB, X( 1, J ), 1, ONE,
00206 $ WORK, 1 )
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217 DO 30 I = 1, N
00218 RWORK( I ) = CABS1( B( I, J ) )
00219 30 CONTINUE
00220
00221
00222
00223 IF( UPPER ) THEN
00224 DO 50 K = 1, N
00225 S = ZERO
00226 XK = CABS1( X( K, J ) )
00227 L = KD + 1 - K
00228 DO 40 I = MAX( 1, K-KD ), K - 1
00229 RWORK( I ) = RWORK( I ) + CABS1( AB( L+I, K ) )*XK
00230 S = S + CABS1( AB( L+I, K ) )*CABS1( X( I, J ) )
00231 40 CONTINUE
00232 RWORK( K ) = RWORK( K ) + ABS( REAL( AB( KD+1, K ) ) )*
00233 $ XK + S
00234 50 CONTINUE
00235 ELSE
00236 DO 70 K = 1, N
00237 S = ZERO
00238 XK = CABS1( X( K, J ) )
00239 RWORK( K ) = RWORK( K ) + ABS( REAL( AB( 1, K ) ) )*XK
00240 L = 1 - K
00241 DO 60 I = K + 1, MIN( N, K+KD )
00242 RWORK( I ) = RWORK( I ) + CABS1( AB( L+I, K ) )*XK
00243 S = S + CABS1( AB( L+I, K ) )*CABS1( X( I, J ) )
00244 60 CONTINUE
00245 RWORK( K ) = RWORK( K ) + S
00246 70 CONTINUE
00247 END IF
00248 S = ZERO
00249 DO 80 I = 1, N
00250 IF( RWORK( I ).GT.SAFE2 ) THEN
00251 S = MAX( S, CABS1( WORK( I ) ) / RWORK( I ) )
00252 ELSE
00253 S = MAX( S, ( CABS1( WORK( I ) )+SAFE1 ) /
00254 $ ( RWORK( I )+SAFE1 ) )
00255 END IF
00256 80 CONTINUE
00257 BERR( J ) = S
00258
00259
00260
00261
00262
00263
00264
00265 IF( BERR( J ).GT.EPS .AND. TWO*BERR( J ).LE.LSTRES .AND.
00266 $ COUNT.LE.ITMAX ) THEN
00267
00268
00269
00270 CALL CPBTRS( UPLO, N, KD, 1, AFB, LDAFB, WORK, N, INFO )
00271 CALL CAXPY( N, ONE, WORK, 1, X( 1, J ), 1 )
00272 LSTRES = BERR( J )
00273 COUNT = COUNT + 1
00274 GO TO 20
00275 END IF
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299 DO 90 I = 1, N
00300 IF( RWORK( I ).GT.SAFE2 ) THEN
00301 RWORK( I ) = CABS1( WORK( I ) ) + NZ*EPS*RWORK( I )
00302 ELSE
00303 RWORK( I ) = CABS1( WORK( I ) ) + NZ*EPS*RWORK( I ) +
00304 $ SAFE1
00305 END IF
00306 90 CONTINUE
00307
00308 KASE = 0
00309 100 CONTINUE
00310 CALL CLACN2( N, WORK( N+1 ), WORK, FERR( J ), KASE, ISAVE )
00311 IF( KASE.NE.0 ) THEN
00312 IF( KASE.EQ.1 ) THEN
00313
00314
00315
00316 CALL CPBTRS( UPLO, N, KD, 1, AFB, LDAFB, WORK, N, INFO )
00317 DO 110 I = 1, N
00318 WORK( I ) = RWORK( I )*WORK( I )
00319 110 CONTINUE
00320 ELSE IF( KASE.EQ.2 ) THEN
00321
00322
00323
00324 DO 120 I = 1, N
00325 WORK( I ) = RWORK( I )*WORK( I )
00326 120 CONTINUE
00327 CALL CPBTRS( UPLO, N, KD, 1, AFB, LDAFB, WORK, N, INFO )
00328 END IF
00329 GO TO 100
00330 END IF
00331
00332
00333
00334 LSTRES = ZERO
00335 DO 130 I = 1, N
00336 LSTRES = MAX( LSTRES, CABS1( X( I, J ) ) )
00337 130 CONTINUE
00338 IF( LSTRES.NE.ZERO )
00339 $ FERR( J ) = FERR( J ) / LSTRES
00340
00341 140 CONTINUE
00342
00343 RETURN
00344
00345
00346
00347 END