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