00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "f2c.h"
00014 #include "blaswrap.h"
00015
00016
00017
00018 static integer c__1 = 1;
00019 static doublereal c_b12 = -1.;
00020 static doublereal c_b14 = 1.;
00021
00022 int dporfs_(char *uplo, integer *n, integer *nrhs,
00023 doublereal *a, integer *lda, doublereal *af, integer *ldaf,
00024 doublereal *b, integer *ldb, doublereal *x, integer *ldx, doublereal *
00025 ferr, doublereal *berr, doublereal *work, integer *iwork, integer *
00026 info)
00027 {
00028
00029 integer a_dim1, a_offset, af_dim1, af_offset, b_dim1, b_offset, x_dim1,
00030 x_offset, i__1, i__2, i__3;
00031 doublereal d__1, d__2, d__3;
00032
00033
00034 integer i__, j, k;
00035 doublereal s, xk;
00036 integer nz;
00037 doublereal eps;
00038 integer kase;
00039 doublereal safe1, safe2;
00040 extern logical lsame_(char *, char *);
00041 integer isave[3];
00042 extern int dcopy_(integer *, doublereal *, integer *,
00043 doublereal *, integer *), daxpy_(integer *, doublereal *,
00044 doublereal *, integer *, doublereal *, integer *);
00045 integer count;
00046 logical upper;
00047 extern int dsymv_(char *, integer *, doublereal *,
00048 doublereal *, integer *, doublereal *, integer *, doublereal *,
00049 doublereal *, integer *), dlacn2_(integer *, doublereal *,
00050 doublereal *, integer *, doublereal *, integer *, integer *);
00051 extern doublereal dlamch_(char *);
00052 doublereal safmin;
00053 extern int xerbla_(char *, integer *), dpotrs_(
00054 char *, integer *, integer *, doublereal *, integer *, doublereal
00055 *, integer *, integer *);
00056 doublereal lstres;
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
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171 a_dim1 = *lda;
00172 a_offset = 1 + a_dim1;
00173 a -= a_offset;
00174 af_dim1 = *ldaf;
00175 af_offset = 1 + af_dim1;
00176 af -= af_offset;
00177 b_dim1 = *ldb;
00178 b_offset = 1 + b_dim1;
00179 b -= b_offset;
00180 x_dim1 = *ldx;
00181 x_offset = 1 + x_dim1;
00182 x -= x_offset;
00183 --ferr;
00184 --berr;
00185 --work;
00186 --iwork;
00187
00188
00189 *info = 0;
00190 upper = lsame_(uplo, "U");
00191 if (! upper && ! lsame_(uplo, "L")) {
00192 *info = -1;
00193 } else if (*n < 0) {
00194 *info = -2;
00195 } else if (*nrhs < 0) {
00196 *info = -3;
00197 } else if (*lda < max(1,*n)) {
00198 *info = -5;
00199 } else if (*ldaf < max(1,*n)) {
00200 *info = -7;
00201 } else if (*ldb < max(1,*n)) {
00202 *info = -9;
00203 } else if (*ldx < max(1,*n)) {
00204 *info = -11;
00205 }
00206 if (*info != 0) {
00207 i__1 = -(*info);
00208 xerbla_("DPORFS", &i__1);
00209 return 0;
00210 }
00211
00212
00213
00214 if (*n == 0 || *nrhs == 0) {
00215 i__1 = *nrhs;
00216 for (j = 1; j <= i__1; ++j) {
00217 ferr[j] = 0.;
00218 berr[j] = 0.;
00219
00220 }
00221 return 0;
00222 }
00223
00224
00225
00226 nz = *n + 1;
00227 eps = dlamch_("Epsilon");
00228 safmin = dlamch_("Safe minimum");
00229 safe1 = nz * safmin;
00230 safe2 = safe1 / eps;
00231
00232
00233
00234 i__1 = *nrhs;
00235 for (j = 1; j <= i__1; ++j) {
00236
00237 count = 1;
00238 lstres = 3.;
00239 L20:
00240
00241
00242
00243
00244
00245 dcopy_(n, &b[j * b_dim1 + 1], &c__1, &work[*n + 1], &c__1);
00246 dsymv_(uplo, n, &c_b12, &a[a_offset], lda, &x[j * x_dim1 + 1], &c__1,
00247 &c_b14, &work[*n + 1], &c__1);
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258 i__2 = *n;
00259 for (i__ = 1; i__ <= i__2; ++i__) {
00260 work[i__] = (d__1 = b[i__ + j * b_dim1], abs(d__1));
00261
00262 }
00263
00264
00265
00266 if (upper) {
00267 i__2 = *n;
00268 for (k = 1; k <= i__2; ++k) {
00269 s = 0.;
00270 xk = (d__1 = x[k + j * x_dim1], abs(d__1));
00271 i__3 = k - 1;
00272 for (i__ = 1; i__ <= i__3; ++i__) {
00273 work[i__] += (d__1 = a[i__ + k * a_dim1], abs(d__1)) * xk;
00274 s += (d__1 = a[i__ + k * a_dim1], abs(d__1)) * (d__2 = x[
00275 i__ + j * x_dim1], abs(d__2));
00276
00277 }
00278 work[k] = work[k] + (d__1 = a[k + k * a_dim1], abs(d__1)) *
00279 xk + s;
00280
00281 }
00282 } else {
00283 i__2 = *n;
00284 for (k = 1; k <= i__2; ++k) {
00285 s = 0.;
00286 xk = (d__1 = x[k + j * x_dim1], abs(d__1));
00287 work[k] += (d__1 = a[k + k * a_dim1], abs(d__1)) * xk;
00288 i__3 = *n;
00289 for (i__ = k + 1; i__ <= i__3; ++i__) {
00290 work[i__] += (d__1 = a[i__ + k * a_dim1], abs(d__1)) * xk;
00291 s += (d__1 = a[i__ + k * a_dim1], abs(d__1)) * (d__2 = x[
00292 i__ + j * x_dim1], abs(d__2));
00293
00294 }
00295 work[k] += s;
00296
00297 }
00298 }
00299 s = 0.;
00300 i__2 = *n;
00301 for (i__ = 1; i__ <= i__2; ++i__) {
00302 if (work[i__] > safe2) {
00303
00304 d__2 = s, d__3 = (d__1 = work[*n + i__], abs(d__1)) / work[
00305 i__];
00306 s = max(d__2,d__3);
00307 } else {
00308
00309 d__2 = s, d__3 = ((d__1 = work[*n + i__], abs(d__1)) + safe1)
00310 / (work[i__] + safe1);
00311 s = max(d__2,d__3);
00312 }
00313
00314 }
00315 berr[j] = s;
00316
00317
00318
00319
00320
00321
00322
00323 if (berr[j] > eps && berr[j] * 2. <= lstres && count <= 5) {
00324
00325
00326
00327 dpotrs_(uplo, n, &c__1, &af[af_offset], ldaf, &work[*n + 1], n,
00328 info);
00329 daxpy_(n, &c_b14, &work[*n + 1], &c__1, &x[j * x_dim1 + 1], &c__1)
00330 ;
00331 lstres = berr[j];
00332 ++count;
00333 goto L20;
00334 }
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 i__2 = *n;
00359 for (i__ = 1; i__ <= i__2; ++i__) {
00360 if (work[i__] > safe2) {
00361 work[i__] = (d__1 = work[*n + i__], abs(d__1)) + nz * eps *
00362 work[i__];
00363 } else {
00364 work[i__] = (d__1 = work[*n + i__], abs(d__1)) + nz * eps *
00365 work[i__] + safe1;
00366 }
00367
00368 }
00369
00370 kase = 0;
00371 L100:
00372 dlacn2_(n, &work[(*n << 1) + 1], &work[*n + 1], &iwork[1], &ferr[j], &
00373 kase, isave);
00374 if (kase != 0) {
00375 if (kase == 1) {
00376
00377
00378
00379 dpotrs_(uplo, n, &c__1, &af[af_offset], ldaf, &work[*n + 1],
00380 n, info);
00381 i__2 = *n;
00382 for (i__ = 1; i__ <= i__2; ++i__) {
00383 work[*n + i__] = work[i__] * work[*n + i__];
00384
00385 }
00386 } else if (kase == 2) {
00387
00388
00389
00390 i__2 = *n;
00391 for (i__ = 1; i__ <= i__2; ++i__) {
00392 work[*n + i__] = work[i__] * work[*n + i__];
00393
00394 }
00395 dpotrs_(uplo, n, &c__1, &af[af_offset], ldaf, &work[*n + 1],
00396 n, info);
00397 }
00398 goto L100;
00399 }
00400
00401
00402
00403 lstres = 0.;
00404 i__2 = *n;
00405 for (i__ = 1; i__ <= i__2; ++i__) {
00406
00407 d__2 = lstres, d__3 = (d__1 = x[i__ + j * x_dim1], abs(d__1));
00408 lstres = max(d__2,d__3);
00409
00410 }
00411 if (lstres != 0.) {
00412 ferr[j] /= lstres;
00413 }
00414
00415
00416 }
00417
00418 return 0;
00419
00420
00421
00422 }