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 doublecomplex c_b1 = {1.,0.};
00019 static integer c__1 = 1;
00020
00021 int zhprfs_(char *uplo, integer *n, integer *nrhs,
00022 doublecomplex *ap, doublecomplex *afp, integer *ipiv, doublecomplex *
00023 b, integer *ldb, doublecomplex *x, integer *ldx, doublereal *ferr,
00024 doublereal *berr, doublecomplex *work, doublereal *rwork, integer *
00025 info)
00026 {
00027
00028 integer b_dim1, b_offset, x_dim1, x_offset, i__1, i__2, i__3, i__4, i__5;
00029 doublereal d__1, d__2, d__3, d__4;
00030 doublecomplex z__1;
00031
00032
00033 double d_imag(doublecomplex *);
00034
00035
00036 integer i__, j, k;
00037 doublereal s;
00038 integer ik, kk;
00039 doublereal xk;
00040 integer nz;
00041 doublereal eps;
00042 integer kase;
00043 doublereal safe1, safe2;
00044 extern logical lsame_(char *, char *);
00045 integer isave[3], count;
00046 logical upper;
00047 extern int zcopy_(integer *, doublecomplex *, integer *,
00048 doublecomplex *, integer *), zhpmv_(char *, integer *,
00049 doublecomplex *, doublecomplex *, doublecomplex *, integer *,
00050 doublecomplex *, doublecomplex *, integer *), zaxpy_(
00051 integer *, doublecomplex *, doublecomplex *, integer *,
00052 doublecomplex *, integer *), zlacn2_(integer *, doublecomplex *,
00053 doublecomplex *, doublereal *, integer *, integer *);
00054 extern doublereal dlamch_(char *);
00055 doublereal safmin;
00056 extern int xerbla_(char *, integer *);
00057 doublereal lstres;
00058 extern int zhptrs_(char *, integer *, integer *,
00059 doublecomplex *, integer *, doublecomplex *, integer *, integer *);
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
00172
00173
00174
00175
00176
00177 --ap;
00178 --afp;
00179 --ipiv;
00180 b_dim1 = *ldb;
00181 b_offset = 1 + b_dim1;
00182 b -= b_offset;
00183 x_dim1 = *ldx;
00184 x_offset = 1 + x_dim1;
00185 x -= x_offset;
00186 --ferr;
00187 --berr;
00188 --work;
00189 --rwork;
00190
00191
00192 *info = 0;
00193 upper = lsame_(uplo, "U");
00194 if (! upper && ! lsame_(uplo, "L")) {
00195 *info = -1;
00196 } else if (*n < 0) {
00197 *info = -2;
00198 } else if (*nrhs < 0) {
00199 *info = -3;
00200 } else if (*ldb < max(1,*n)) {
00201 *info = -8;
00202 } else if (*ldx < max(1,*n)) {
00203 *info = -10;
00204 }
00205 if (*info != 0) {
00206 i__1 = -(*info);
00207 xerbla_("ZHPRFS", &i__1);
00208 return 0;
00209 }
00210
00211
00212
00213 if (*n == 0 || *nrhs == 0) {
00214 i__1 = *nrhs;
00215 for (j = 1; j <= i__1; ++j) {
00216 ferr[j] = 0.;
00217 berr[j] = 0.;
00218
00219 }
00220 return 0;
00221 }
00222
00223
00224
00225 nz = *n + 1;
00226 eps = dlamch_("Epsilon");
00227 safmin = dlamch_("Safe minimum");
00228 safe1 = nz * safmin;
00229 safe2 = safe1 / eps;
00230
00231
00232
00233 i__1 = *nrhs;
00234 for (j = 1; j <= i__1; ++j) {
00235
00236 count = 1;
00237 lstres = 3.;
00238 L20:
00239
00240
00241
00242
00243
00244 zcopy_(n, &b[j * b_dim1 + 1], &c__1, &work[1], &c__1);
00245 z__1.r = -1., z__1.i = -0.;
00246 zhpmv_(uplo, n, &z__1, &ap[1], &x[j * x_dim1 + 1], &c__1, &c_b1, &
00247 work[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 i__3 = i__ + j * b_dim1;
00261 rwork[i__] = (d__1 = b[i__3].r, abs(d__1)) + (d__2 = d_imag(&b[
00262 i__ + j * b_dim1]), abs(d__2));
00263
00264 }
00265
00266
00267
00268 kk = 1;
00269 if (upper) {
00270 i__2 = *n;
00271 for (k = 1; k <= i__2; ++k) {
00272 s = 0.;
00273 i__3 = k + j * x_dim1;
00274 xk = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(&x[k + j *
00275 x_dim1]), abs(d__2));
00276 ik = kk;
00277 i__3 = k - 1;
00278 for (i__ = 1; i__ <= i__3; ++i__) {
00279 i__4 = ik;
00280 rwork[i__] += ((d__1 = ap[i__4].r, abs(d__1)) + (d__2 =
00281 d_imag(&ap[ik]), abs(d__2))) * xk;
00282 i__4 = ik;
00283 i__5 = i__ + j * x_dim1;
00284 s += ((d__1 = ap[i__4].r, abs(d__1)) + (d__2 = d_imag(&ap[
00285 ik]), abs(d__2))) * ((d__3 = x[i__5].r, abs(d__3))
00286 + (d__4 = d_imag(&x[i__ + j * x_dim1]), abs(d__4)
00287 ));
00288 ++ik;
00289
00290 }
00291 i__3 = kk + k - 1;
00292 rwork[k] = rwork[k] + (d__1 = ap[i__3].r, abs(d__1)) * xk + s;
00293 kk += k;
00294
00295 }
00296 } else {
00297 i__2 = *n;
00298 for (k = 1; k <= i__2; ++k) {
00299 s = 0.;
00300 i__3 = k + j * x_dim1;
00301 xk = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(&x[k + j *
00302 x_dim1]), abs(d__2));
00303 i__3 = kk;
00304 rwork[k] += (d__1 = ap[i__3].r, abs(d__1)) * xk;
00305 ik = kk + 1;
00306 i__3 = *n;
00307 for (i__ = k + 1; i__ <= i__3; ++i__) {
00308 i__4 = ik;
00309 rwork[i__] += ((d__1 = ap[i__4].r, abs(d__1)) + (d__2 =
00310 d_imag(&ap[ik]), abs(d__2))) * xk;
00311 i__4 = ik;
00312 i__5 = i__ + j * x_dim1;
00313 s += ((d__1 = ap[i__4].r, abs(d__1)) + (d__2 = d_imag(&ap[
00314 ik]), abs(d__2))) * ((d__3 = x[i__5].r, abs(d__3))
00315 + (d__4 = d_imag(&x[i__ + j * x_dim1]), abs(d__4)
00316 ));
00317 ++ik;
00318
00319 }
00320 rwork[k] += s;
00321 kk += *n - k + 1;
00322
00323 }
00324 }
00325 s = 0.;
00326 i__2 = *n;
00327 for (i__ = 1; i__ <= i__2; ++i__) {
00328 if (rwork[i__] > safe2) {
00329
00330 i__3 = i__;
00331 d__3 = s, d__4 = ((d__1 = work[i__3].r, abs(d__1)) + (d__2 =
00332 d_imag(&work[i__]), abs(d__2))) / rwork[i__];
00333 s = max(d__3,d__4);
00334 } else {
00335
00336 i__3 = i__;
00337 d__3 = s, d__4 = ((d__1 = work[i__3].r, abs(d__1)) + (d__2 =
00338 d_imag(&work[i__]), abs(d__2)) + safe1) / (rwork[i__]
00339 + safe1);
00340 s = max(d__3,d__4);
00341 }
00342
00343 }
00344 berr[j] = s;
00345
00346
00347
00348
00349
00350
00351
00352 if (berr[j] > eps && berr[j] * 2. <= lstres && count <= 5) {
00353
00354
00355
00356 zhptrs_(uplo, n, &c__1, &afp[1], &ipiv[1], &work[1], n, info);
00357 zaxpy_(n, &c_b1, &work[1], &c__1, &x[j * x_dim1 + 1], &c__1);
00358 lstres = berr[j];
00359 ++count;
00360 goto L20;
00361 }
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385 i__2 = *n;
00386 for (i__ = 1; i__ <= i__2; ++i__) {
00387 if (rwork[i__] > safe2) {
00388 i__3 = i__;
00389 rwork[i__] = (d__1 = work[i__3].r, abs(d__1)) + (d__2 =
00390 d_imag(&work[i__]), abs(d__2)) + nz * eps * rwork[i__]
00391 ;
00392 } else {
00393 i__3 = i__;
00394 rwork[i__] = (d__1 = work[i__3].r, abs(d__1)) + (d__2 =
00395 d_imag(&work[i__]), abs(d__2)) + nz * eps * rwork[i__]
00396 + safe1;
00397 }
00398
00399 }
00400
00401 kase = 0;
00402 L100:
00403 zlacn2_(n, &work[*n + 1], &work[1], &ferr[j], &kase, isave);
00404 if (kase != 0) {
00405 if (kase == 1) {
00406
00407
00408
00409 zhptrs_(uplo, n, &c__1, &afp[1], &ipiv[1], &work[1], n, info);
00410 i__2 = *n;
00411 for (i__ = 1; i__ <= i__2; ++i__) {
00412 i__3 = i__;
00413 i__4 = i__;
00414 i__5 = i__;
00415 z__1.r = rwork[i__4] * work[i__5].r, z__1.i = rwork[i__4]
00416 * work[i__5].i;
00417 work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00418
00419 }
00420 } else if (kase == 2) {
00421
00422
00423
00424 i__2 = *n;
00425 for (i__ = 1; i__ <= i__2; ++i__) {
00426 i__3 = i__;
00427 i__4 = i__;
00428 i__5 = i__;
00429 z__1.r = rwork[i__4] * work[i__5].r, z__1.i = rwork[i__4]
00430 * work[i__5].i;
00431 work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00432
00433 }
00434 zhptrs_(uplo, n, &c__1, &afp[1], &ipiv[1], &work[1], n, info);
00435 }
00436 goto L100;
00437 }
00438
00439
00440
00441 lstres = 0.;
00442 i__2 = *n;
00443 for (i__ = 1; i__ <= i__2; ++i__) {
00444
00445 i__3 = i__ + j * x_dim1;
00446 d__3 = lstres, d__4 = (d__1 = x[i__3].r, abs(d__1)) + (d__2 =
00447 d_imag(&x[i__ + j * x_dim1]), abs(d__2));
00448 lstres = max(d__3,d__4);
00449
00450 }
00451 if (lstres != 0.) {
00452 ferr[j] /= lstres;
00453 }
00454
00455
00456 }
00457
00458 return 0;
00459
00460
00461
00462 }