00001 SUBROUTINE CPTRFS( UPLO, N, NRHS, D, E, DF, EF, B, LDB, X, LDX,
00002 $ FERR, BERR, WORK, RWORK, INFO )
00003
00004
00005
00006
00007
00008
00009
00010 CHARACTER UPLO
00011 INTEGER INFO, LDB, LDX, N, NRHS
00012
00013
00014 REAL BERR( * ), D( * ), DF( * ), FERR( * ),
00015 $ RWORK( * )
00016 COMPLEX B( LDB, * ), E( * ), EF( * ), WORK( * ),
00017 $ X( LDX, * )
00018
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 INTEGER ITMAX
00105 PARAMETER ( ITMAX = 5 )
00106 REAL ZERO
00107 PARAMETER ( ZERO = 0.0E+0 )
00108 REAL ONE
00109 PARAMETER ( ONE = 1.0E+0 )
00110 REAL TWO
00111 PARAMETER ( TWO = 2.0E+0 )
00112 REAL THREE
00113 PARAMETER ( THREE = 3.0E+0 )
00114
00115
00116 LOGICAL UPPER
00117 INTEGER COUNT, I, IX, J, NZ
00118 REAL EPS, LSTRES, S, SAFE1, SAFE2, SAFMIN
00119 COMPLEX BI, CX, DX, EX, ZDUM
00120
00121
00122 LOGICAL LSAME
00123 INTEGER ISAMAX
00124 REAL SLAMCH
00125 EXTERNAL LSAME, ISAMAX, SLAMCH
00126
00127
00128 EXTERNAL CAXPY, CPTTRS, XERBLA
00129
00130
00131 INTRINSIC ABS, AIMAG, CMPLX, CONJG, MAX, REAL
00132
00133
00134 REAL CABS1
00135
00136
00137 CABS1( ZDUM ) = ABS( REAL( ZDUM ) ) + ABS( AIMAG( ZDUM ) )
00138
00139
00140
00141
00142
00143 INFO = 0
00144 UPPER = LSAME( UPLO, 'U' )
00145 IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
00146 INFO = -1
00147 ELSE IF( N.LT.0 ) THEN
00148 INFO = -2
00149 ELSE IF( NRHS.LT.0 ) THEN
00150 INFO = -3
00151 ELSE IF( LDB.LT.MAX( 1, N ) ) THEN
00152 INFO = -9
00153 ELSE IF( LDX.LT.MAX( 1, N ) ) THEN
00154 INFO = -11
00155 END IF
00156 IF( INFO.NE.0 ) THEN
00157 CALL XERBLA( 'CPTRFS', -INFO )
00158 RETURN
00159 END IF
00160
00161
00162
00163 IF( N.EQ.0 .OR. NRHS.EQ.0 ) THEN
00164 DO 10 J = 1, NRHS
00165 FERR( J ) = ZERO
00166 BERR( J ) = ZERO
00167 10 CONTINUE
00168 RETURN
00169 END IF
00170
00171
00172
00173 NZ = 4
00174 EPS = SLAMCH( 'Epsilon' )
00175 SAFMIN = SLAMCH( 'Safe minimum' )
00176 SAFE1 = NZ*SAFMIN
00177 SAFE2 = SAFE1 / EPS
00178
00179
00180
00181 DO 100 J = 1, NRHS
00182
00183 COUNT = 1
00184 LSTRES = THREE
00185 20 CONTINUE
00186
00187
00188
00189
00190
00191
00192 IF( UPPER ) THEN
00193 IF( N.EQ.1 ) THEN
00194 BI = B( 1, J )
00195 DX = D( 1 )*X( 1, J )
00196 WORK( 1 ) = BI - DX
00197 RWORK( 1 ) = CABS1( BI ) + CABS1( DX )
00198 ELSE
00199 BI = B( 1, J )
00200 DX = D( 1 )*X( 1, J )
00201 EX = E( 1 )*X( 2, J )
00202 WORK( 1 ) = BI - DX - EX
00203 RWORK( 1 ) = CABS1( BI ) + CABS1( DX ) +
00204 $ CABS1( E( 1 ) )*CABS1( X( 2, J ) )
00205 DO 30 I = 2, N - 1
00206 BI = B( I, J )
00207 CX = CONJG( E( I-1 ) )*X( I-1, J )
00208 DX = D( I )*X( I, J )
00209 EX = E( I )*X( I+1, J )
00210 WORK( I ) = BI - CX - DX - EX
00211 RWORK( I ) = CABS1( BI ) +
00212 $ CABS1( E( I-1 ) )*CABS1( X( I-1, J ) ) +
00213 $ CABS1( DX ) + CABS1( E( I ) )*
00214 $ CABS1( X( I+1, J ) )
00215 30 CONTINUE
00216 BI = B( N, J )
00217 CX = CONJG( E( N-1 ) )*X( N-1, J )
00218 DX = D( N )*X( N, J )
00219 WORK( N ) = BI - CX - DX
00220 RWORK( N ) = CABS1( BI ) + CABS1( E( N-1 ) )*
00221 $ CABS1( X( N-1, J ) ) + CABS1( DX )
00222 END IF
00223 ELSE
00224 IF( N.EQ.1 ) THEN
00225 BI = B( 1, J )
00226 DX = D( 1 )*X( 1, J )
00227 WORK( 1 ) = BI - DX
00228 RWORK( 1 ) = CABS1( BI ) + CABS1( DX )
00229 ELSE
00230 BI = B( 1, J )
00231 DX = D( 1 )*X( 1, J )
00232 EX = CONJG( E( 1 ) )*X( 2, J )
00233 WORK( 1 ) = BI - DX - EX
00234 RWORK( 1 ) = CABS1( BI ) + CABS1( DX ) +
00235 $ CABS1( E( 1 ) )*CABS1( X( 2, J ) )
00236 DO 40 I = 2, N - 1
00237 BI = B( I, J )
00238 CX = E( I-1 )*X( I-1, J )
00239 DX = D( I )*X( I, J )
00240 EX = CONJG( E( I ) )*X( I+1, J )
00241 WORK( I ) = BI - CX - DX - EX
00242 RWORK( I ) = CABS1( BI ) +
00243 $ CABS1( E( I-1 ) )*CABS1( X( I-1, J ) ) +
00244 $ CABS1( DX ) + CABS1( E( I ) )*
00245 $ CABS1( X( I+1, J ) )
00246 40 CONTINUE
00247 BI = B( N, J )
00248 CX = E( N-1 )*X( N-1, J )
00249 DX = D( N )*X( N, J )
00250 WORK( N ) = BI - CX - DX
00251 RWORK( N ) = CABS1( BI ) + CABS1( E( N-1 ) )*
00252 $ CABS1( X( N-1, J ) ) + CABS1( DX )
00253 END IF
00254 END IF
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 S = ZERO
00266 DO 50 I = 1, N
00267 IF( RWORK( I ).GT.SAFE2 ) THEN
00268 S = MAX( S, CABS1( WORK( I ) ) / RWORK( I ) )
00269 ELSE
00270 S = MAX( S, ( CABS1( WORK( I ) )+SAFE1 ) /
00271 $ ( RWORK( I )+SAFE1 ) )
00272 END IF
00273 50 CONTINUE
00274 BERR( J ) = S
00275
00276
00277
00278
00279
00280
00281
00282 IF( BERR( J ).GT.EPS .AND. TWO*BERR( J ).LE.LSTRES .AND.
00283 $ COUNT.LE.ITMAX ) THEN
00284
00285
00286
00287 CALL CPTTRS( UPLO, N, 1, DF, EF, WORK, N, INFO )
00288 CALL CAXPY( N, CMPLX( ONE ), WORK, 1, X( 1, J ), 1 )
00289 LSTRES = BERR( J )
00290 COUNT = COUNT + 1
00291 GO TO 20
00292 END IF
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 DO 60 I = 1, N
00313 IF( RWORK( I ).GT.SAFE2 ) THEN
00314 RWORK( I ) = CABS1( WORK( I ) ) + NZ*EPS*RWORK( I )
00315 ELSE
00316 RWORK( I ) = CABS1( WORK( I ) ) + NZ*EPS*RWORK( I ) +
00317 $ SAFE1
00318 END IF
00319 60 CONTINUE
00320 IX = ISAMAX( N, RWORK, 1 )
00321 FERR( J ) = RWORK( IX )
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334 RWORK( 1 ) = ONE
00335 DO 70 I = 2, N
00336 RWORK( I ) = ONE + RWORK( I-1 )*ABS( EF( I-1 ) )
00337 70 CONTINUE
00338
00339
00340
00341 RWORK( N ) = RWORK( N ) / DF( N )
00342 DO 80 I = N - 1, 1, -1
00343 RWORK( I ) = RWORK( I ) / DF( I ) +
00344 $ RWORK( I+1 )*ABS( EF( I ) )
00345 80 CONTINUE
00346
00347
00348
00349 IX = ISAMAX( N, RWORK, 1 )
00350 FERR( J ) = FERR( J )*ABS( RWORK( IX ) )
00351
00352
00353
00354 LSTRES = ZERO
00355 DO 90 I = 1, N
00356 LSTRES = MAX( LSTRES, ABS( X( I, J ) ) )
00357 90 CONTINUE
00358 IF( LSTRES.NE.ZERO )
00359 $ FERR( J ) = FERR( J ) / LSTRES
00360
00361 100 CONTINUE
00362
00363 RETURN
00364
00365
00366
00367 END