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