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