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