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 doublecomplex c_b16 = {1.,0.};
00020
00021 int zptrfs_(char *uplo, integer *n, integer *nrhs,
00022 doublereal *d__, doublecomplex *e, doublereal *df, doublecomplex *ef,
00023 doublecomplex *b, integer *ldb, doublecomplex *x, integer *ldx,
00024 doublereal *ferr, doublereal *berr, doublecomplex *work, doublereal *
00025 rwork, integer *info)
00026 {
00027
00028 integer b_dim1, b_offset, x_dim1, x_offset, i__1, i__2, i__3, i__4, i__5,
00029 i__6;
00030 doublereal d__1, d__2, d__3, d__4, d__5, d__6, d__7, d__8, d__9, d__10,
00031 d__11, d__12;
00032 doublecomplex z__1, z__2, z__3;
00033
00034
00035 double d_imag(doublecomplex *);
00036 void d_cnjg(doublecomplex *, doublecomplex *);
00037 double z_abs(doublecomplex *);
00038
00039
00040 integer i__, j;
00041 doublereal s;
00042 doublecomplex bi, cx, dx, ex;
00043 integer ix, nz;
00044 doublereal eps, safe1, safe2;
00045 extern logical lsame_(char *, char *);
00046 integer count;
00047 logical upper;
00048 extern int zaxpy_(integer *, doublecomplex *,
00049 doublecomplex *, integer *, doublecomplex *, integer *);
00050 extern doublereal dlamch_(char *);
00051 extern integer idamax_(integer *, doublereal *, integer *);
00052 doublereal safmin;
00053 extern int xerbla_(char *, integer *);
00054 doublereal lstres;
00055 extern int zpttrs_(char *, integer *, integer *,
00056 doublereal *, doublecomplex *, doublecomplex *, integer *,
00057 integer *);
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 --d__;
00172 --e;
00173 --df;
00174 --ef;
00175 b_dim1 = *ldb;
00176 b_offset = 1 + b_dim1;
00177 b -= b_offset;
00178 x_dim1 = *ldx;
00179 x_offset = 1 + x_dim1;
00180 x -= x_offset;
00181 --ferr;
00182 --berr;
00183 --work;
00184 --rwork;
00185
00186
00187 *info = 0;
00188 upper = lsame_(uplo, "U");
00189 if (! upper && ! lsame_(uplo, "L")) {
00190 *info = -1;
00191 } else if (*n < 0) {
00192 *info = -2;
00193 } else if (*nrhs < 0) {
00194 *info = -3;
00195 } else if (*ldb < max(1,*n)) {
00196 *info = -9;
00197 } else if (*ldx < max(1,*n)) {
00198 *info = -11;
00199 }
00200 if (*info != 0) {
00201 i__1 = -(*info);
00202 xerbla_("ZPTRFS", &i__1);
00203 return 0;
00204 }
00205
00206
00207
00208 if (*n == 0 || *nrhs == 0) {
00209 i__1 = *nrhs;
00210 for (j = 1; j <= i__1; ++j) {
00211 ferr[j] = 0.;
00212 berr[j] = 0.;
00213
00214 }
00215 return 0;
00216 }
00217
00218
00219
00220 nz = 4;
00221 eps = dlamch_("Epsilon");
00222 safmin = dlamch_("Safe minimum");
00223 safe1 = nz * safmin;
00224 safe2 = safe1 / eps;
00225
00226
00227
00228 i__1 = *nrhs;
00229 for (j = 1; j <= i__1; ++j) {
00230
00231 count = 1;
00232 lstres = 3.;
00233 L20:
00234
00235
00236
00237
00238
00239
00240 if (upper) {
00241 if (*n == 1) {
00242 i__2 = j * b_dim1 + 1;
00243 bi.r = b[i__2].r, bi.i = b[i__2].i;
00244 i__2 = j * x_dim1 + 1;
00245 z__1.r = d__[1] * x[i__2].r, z__1.i = d__[1] * x[i__2].i;
00246 dx.r = z__1.r, dx.i = z__1.i;
00247 z__1.r = bi.r - dx.r, z__1.i = bi.i - dx.i;
00248 work[1].r = z__1.r, work[1].i = z__1.i;
00249 rwork[1] = (d__1 = bi.r, abs(d__1)) + (d__2 = d_imag(&bi),
00250 abs(d__2)) + ((d__3 = dx.r, abs(d__3)) + (d__4 =
00251 d_imag(&dx), abs(d__4)));
00252 } else {
00253 i__2 = j * b_dim1 + 1;
00254 bi.r = b[i__2].r, bi.i = b[i__2].i;
00255 i__2 = j * x_dim1 + 1;
00256 z__1.r = d__[1] * x[i__2].r, z__1.i = d__[1] * x[i__2].i;
00257 dx.r = z__1.r, dx.i = z__1.i;
00258 i__2 = j * x_dim1 + 2;
00259 z__1.r = e[1].r * x[i__2].r - e[1].i * x[i__2].i, z__1.i = e[
00260 1].r * x[i__2].i + e[1].i * x[i__2].r;
00261 ex.r = z__1.r, ex.i = z__1.i;
00262 z__2.r = bi.r - dx.r, z__2.i = bi.i - dx.i;
00263 z__1.r = z__2.r - ex.r, z__1.i = z__2.i - ex.i;
00264 work[1].r = z__1.r, work[1].i = z__1.i;
00265 i__2 = j * x_dim1 + 2;
00266 rwork[1] = (d__1 = bi.r, abs(d__1)) + (d__2 = d_imag(&bi),
00267 abs(d__2)) + ((d__3 = dx.r, abs(d__3)) + (d__4 =
00268 d_imag(&dx), abs(d__4))) + ((d__5 = e[1].r, abs(d__5))
00269 + (d__6 = d_imag(&e[1]), abs(d__6))) * ((d__7 = x[
00270 i__2].r, abs(d__7)) + (d__8 = d_imag(&x[j * x_dim1 +
00271 2]), abs(d__8)));
00272 i__2 = *n - 1;
00273 for (i__ = 2; i__ <= i__2; ++i__) {
00274 i__3 = i__ + j * b_dim1;
00275 bi.r = b[i__3].r, bi.i = b[i__3].i;
00276 d_cnjg(&z__2, &e[i__ - 1]);
00277 i__3 = i__ - 1 + j * x_dim1;
00278 z__1.r = z__2.r * x[i__3].r - z__2.i * x[i__3].i, z__1.i =
00279 z__2.r * x[i__3].i + z__2.i * x[i__3].r;
00280 cx.r = z__1.r, cx.i = z__1.i;
00281 i__3 = i__;
00282 i__4 = i__ + j * x_dim1;
00283 z__1.r = d__[i__3] * x[i__4].r, z__1.i = d__[i__3] * x[
00284 i__4].i;
00285 dx.r = z__1.r, dx.i = z__1.i;
00286 i__3 = i__;
00287 i__4 = i__ + 1 + j * x_dim1;
00288 z__1.r = e[i__3].r * x[i__4].r - e[i__3].i * x[i__4].i,
00289 z__1.i = e[i__3].r * x[i__4].i + e[i__3].i * x[
00290 i__4].r;
00291 ex.r = z__1.r, ex.i = z__1.i;
00292 i__3 = i__;
00293 z__3.r = bi.r - cx.r, z__3.i = bi.i - cx.i;
00294 z__2.r = z__3.r - dx.r, z__2.i = z__3.i - dx.i;
00295 z__1.r = z__2.r - ex.r, z__1.i = z__2.i - ex.i;
00296 work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00297 i__3 = i__ - 1;
00298 i__4 = i__ - 1 + j * x_dim1;
00299 i__5 = i__;
00300 i__6 = i__ + 1 + j * x_dim1;
00301 rwork[i__] = (d__1 = bi.r, abs(d__1)) + (d__2 = d_imag(&
00302 bi), abs(d__2)) + ((d__3 = e[i__3].r, abs(d__3))
00303 + (d__4 = d_imag(&e[i__ - 1]), abs(d__4))) * ((
00304 d__5 = x[i__4].r, abs(d__5)) + (d__6 = d_imag(&x[
00305 i__ - 1 + j * x_dim1]), abs(d__6))) + ((d__7 =
00306 dx.r, abs(d__7)) + (d__8 = d_imag(&dx), abs(d__8))
00307 ) + ((d__9 = e[i__5].r, abs(d__9)) + (d__10 =
00308 d_imag(&e[i__]), abs(d__10))) * ((d__11 = x[i__6]
00309 .r, abs(d__11)) + (d__12 = d_imag(&x[i__ + 1 + j *
00310 x_dim1]), abs(d__12)));
00311
00312 }
00313 i__2 = *n + j * b_dim1;
00314 bi.r = b[i__2].r, bi.i = b[i__2].i;
00315 d_cnjg(&z__2, &e[*n - 1]);
00316 i__2 = *n - 1 + j * x_dim1;
00317 z__1.r = z__2.r * x[i__2].r - z__2.i * x[i__2].i, z__1.i =
00318 z__2.r * x[i__2].i + z__2.i * x[i__2].r;
00319 cx.r = z__1.r, cx.i = z__1.i;
00320 i__2 = *n;
00321 i__3 = *n + j * x_dim1;
00322 z__1.r = d__[i__2] * x[i__3].r, z__1.i = d__[i__2] * x[i__3]
00323 .i;
00324 dx.r = z__1.r, dx.i = z__1.i;
00325 i__2 = *n;
00326 z__2.r = bi.r - cx.r, z__2.i = bi.i - cx.i;
00327 z__1.r = z__2.r - dx.r, z__1.i = z__2.i - dx.i;
00328 work[i__2].r = z__1.r, work[i__2].i = z__1.i;
00329 i__2 = *n - 1;
00330 i__3 = *n - 1 + j * x_dim1;
00331 rwork[*n] = (d__1 = bi.r, abs(d__1)) + (d__2 = d_imag(&bi),
00332 abs(d__2)) + ((d__3 = e[i__2].r, abs(d__3)) + (d__4 =
00333 d_imag(&e[*n - 1]), abs(d__4))) * ((d__5 = x[i__3].r,
00334 abs(d__5)) + (d__6 = d_imag(&x[*n - 1 + j * x_dim1]),
00335 abs(d__6))) + ((d__7 = dx.r, abs(d__7)) + (d__8 =
00336 d_imag(&dx), abs(d__8)));
00337 }
00338 } else {
00339 if (*n == 1) {
00340 i__2 = j * b_dim1 + 1;
00341 bi.r = b[i__2].r, bi.i = b[i__2].i;
00342 i__2 = j * x_dim1 + 1;
00343 z__1.r = d__[1] * x[i__2].r, z__1.i = d__[1] * x[i__2].i;
00344 dx.r = z__1.r, dx.i = z__1.i;
00345 z__1.r = bi.r - dx.r, z__1.i = bi.i - dx.i;
00346 work[1].r = z__1.r, work[1].i = z__1.i;
00347 rwork[1] = (d__1 = bi.r, abs(d__1)) + (d__2 = d_imag(&bi),
00348 abs(d__2)) + ((d__3 = dx.r, abs(d__3)) + (d__4 =
00349 d_imag(&dx), abs(d__4)));
00350 } else {
00351 i__2 = j * b_dim1 + 1;
00352 bi.r = b[i__2].r, bi.i = b[i__2].i;
00353 i__2 = j * x_dim1 + 1;
00354 z__1.r = d__[1] * x[i__2].r, z__1.i = d__[1] * x[i__2].i;
00355 dx.r = z__1.r, dx.i = z__1.i;
00356 d_cnjg(&z__2, &e[1]);
00357 i__2 = j * x_dim1 + 2;
00358 z__1.r = z__2.r * x[i__2].r - z__2.i * x[i__2].i, z__1.i =
00359 z__2.r * x[i__2].i + z__2.i * x[i__2].r;
00360 ex.r = z__1.r, ex.i = z__1.i;
00361 z__2.r = bi.r - dx.r, z__2.i = bi.i - dx.i;
00362 z__1.r = z__2.r - ex.r, z__1.i = z__2.i - ex.i;
00363 work[1].r = z__1.r, work[1].i = z__1.i;
00364 i__2 = j * x_dim1 + 2;
00365 rwork[1] = (d__1 = bi.r, abs(d__1)) + (d__2 = d_imag(&bi),
00366 abs(d__2)) + ((d__3 = dx.r, abs(d__3)) + (d__4 =
00367 d_imag(&dx), abs(d__4))) + ((d__5 = e[1].r, abs(d__5))
00368 + (d__6 = d_imag(&e[1]), abs(d__6))) * ((d__7 = x[
00369 i__2].r, abs(d__7)) + (d__8 = d_imag(&x[j * x_dim1 +
00370 2]), abs(d__8)));
00371 i__2 = *n - 1;
00372 for (i__ = 2; i__ <= i__2; ++i__) {
00373 i__3 = i__ + j * b_dim1;
00374 bi.r = b[i__3].r, bi.i = b[i__3].i;
00375 i__3 = i__ - 1;
00376 i__4 = i__ - 1 + j * x_dim1;
00377 z__1.r = e[i__3].r * x[i__4].r - e[i__3].i * x[i__4].i,
00378 z__1.i = e[i__3].r * x[i__4].i + e[i__3].i * x[
00379 i__4].r;
00380 cx.r = z__1.r, cx.i = z__1.i;
00381 i__3 = i__;
00382 i__4 = i__ + j * x_dim1;
00383 z__1.r = d__[i__3] * x[i__4].r, z__1.i = d__[i__3] * x[
00384 i__4].i;
00385 dx.r = z__1.r, dx.i = z__1.i;
00386 d_cnjg(&z__2, &e[i__]);
00387 i__3 = i__ + 1 + j * x_dim1;
00388 z__1.r = z__2.r * x[i__3].r - z__2.i * x[i__3].i, z__1.i =
00389 z__2.r * x[i__3].i + z__2.i * x[i__3].r;
00390 ex.r = z__1.r, ex.i = z__1.i;
00391 i__3 = i__;
00392 z__3.r = bi.r - cx.r, z__3.i = bi.i - cx.i;
00393 z__2.r = z__3.r - dx.r, z__2.i = z__3.i - dx.i;
00394 z__1.r = z__2.r - ex.r, z__1.i = z__2.i - ex.i;
00395 work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00396 i__3 = i__ - 1;
00397 i__4 = i__ - 1 + j * x_dim1;
00398 i__5 = i__;
00399 i__6 = i__ + 1 + j * x_dim1;
00400 rwork[i__] = (d__1 = bi.r, abs(d__1)) + (d__2 = d_imag(&
00401 bi), abs(d__2)) + ((d__3 = e[i__3].r, abs(d__3))
00402 + (d__4 = d_imag(&e[i__ - 1]), abs(d__4))) * ((
00403 d__5 = x[i__4].r, abs(d__5)) + (d__6 = d_imag(&x[
00404 i__ - 1 + j * x_dim1]), abs(d__6))) + ((d__7 =
00405 dx.r, abs(d__7)) + (d__8 = d_imag(&dx), abs(d__8))
00406 ) + ((d__9 = e[i__5].r, abs(d__9)) + (d__10 =
00407 d_imag(&e[i__]), abs(d__10))) * ((d__11 = x[i__6]
00408 .r, abs(d__11)) + (d__12 = d_imag(&x[i__ + 1 + j *
00409 x_dim1]), abs(d__12)));
00410
00411 }
00412 i__2 = *n + j * b_dim1;
00413 bi.r = b[i__2].r, bi.i = b[i__2].i;
00414 i__2 = *n - 1;
00415 i__3 = *n - 1 + j * x_dim1;
00416 z__1.r = e[i__2].r * x[i__3].r - e[i__2].i * x[i__3].i,
00417 z__1.i = e[i__2].r * x[i__3].i + e[i__2].i * x[i__3]
00418 .r;
00419 cx.r = z__1.r, cx.i = z__1.i;
00420 i__2 = *n;
00421 i__3 = *n + j * x_dim1;
00422 z__1.r = d__[i__2] * x[i__3].r, z__1.i = d__[i__2] * x[i__3]
00423 .i;
00424 dx.r = z__1.r, dx.i = z__1.i;
00425 i__2 = *n;
00426 z__2.r = bi.r - cx.r, z__2.i = bi.i - cx.i;
00427 z__1.r = z__2.r - dx.r, z__1.i = z__2.i - dx.i;
00428 work[i__2].r = z__1.r, work[i__2].i = z__1.i;
00429 i__2 = *n - 1;
00430 i__3 = *n - 1 + j * x_dim1;
00431 rwork[*n] = (d__1 = bi.r, abs(d__1)) + (d__2 = d_imag(&bi),
00432 abs(d__2)) + ((d__3 = e[i__2].r, abs(d__3)) + (d__4 =
00433 d_imag(&e[*n - 1]), abs(d__4))) * ((d__5 = x[i__3].r,
00434 abs(d__5)) + (d__6 = d_imag(&x[*n - 1 + j * x_dim1]),
00435 abs(d__6))) + ((d__7 = dx.r, abs(d__7)) + (d__8 =
00436 d_imag(&dx), abs(d__8)));
00437 }
00438 }
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449 s = 0.;
00450 i__2 = *n;
00451 for (i__ = 1; i__ <= i__2; ++i__) {
00452 if (rwork[i__] > safe2) {
00453
00454 i__3 = i__;
00455 d__3 = s, d__4 = ((d__1 = work[i__3].r, abs(d__1)) + (d__2 =
00456 d_imag(&work[i__]), abs(d__2))) / rwork[i__];
00457 s = max(d__3,d__4);
00458 } else {
00459
00460 i__3 = i__;
00461 d__3 = s, d__4 = ((d__1 = work[i__3].r, abs(d__1)) + (d__2 =
00462 d_imag(&work[i__]), abs(d__2)) + safe1) / (rwork[i__]
00463 + safe1);
00464 s = max(d__3,d__4);
00465 }
00466
00467 }
00468 berr[j] = s;
00469
00470
00471
00472
00473
00474
00475
00476 if (berr[j] > eps && berr[j] * 2. <= lstres && count <= 5) {
00477
00478
00479
00480 zpttrs_(uplo, n, &c__1, &df[1], &ef[1], &work[1], n, info);
00481 zaxpy_(n, &c_b16, &work[1], &c__1, &x[j * x_dim1 + 1], &c__1);
00482 lstres = berr[j];
00483 ++count;
00484 goto L20;
00485 }
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503
00504
00505 i__2 = *n;
00506 for (i__ = 1; i__ <= i__2; ++i__) {
00507 if (rwork[i__] > safe2) {
00508 i__3 = i__;
00509 rwork[i__] = (d__1 = work[i__3].r, abs(d__1)) + (d__2 =
00510 d_imag(&work[i__]), abs(d__2)) + nz * eps * rwork[i__]
00511 ;
00512 } else {
00513 i__3 = i__;
00514 rwork[i__] = (d__1 = work[i__3].r, abs(d__1)) + (d__2 =
00515 d_imag(&work[i__]), abs(d__2)) + nz * eps * rwork[i__]
00516 + safe1;
00517 }
00518
00519 }
00520 ix = idamax_(n, &rwork[1], &c__1);
00521 ferr[j] = rwork[ix];
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534 rwork[1] = 1.;
00535 i__2 = *n;
00536 for (i__ = 2; i__ <= i__2; ++i__) {
00537 rwork[i__] = rwork[i__ - 1] * z_abs(&ef[i__ - 1]) + 1.;
00538
00539 }
00540
00541
00542
00543 rwork[*n] /= df[*n];
00544 for (i__ = *n - 1; i__ >= 1; --i__) {
00545 rwork[i__] = rwork[i__] / df[i__] + rwork[i__ + 1] * z_abs(&ef[
00546 i__]);
00547
00548 }
00549
00550
00551
00552 ix = idamax_(n, &rwork[1], &c__1);
00553 ferr[j] *= (d__1 = rwork[ix], abs(d__1));
00554
00555
00556
00557 lstres = 0.;
00558 i__2 = *n;
00559 for (i__ = 1; i__ <= i__2; ++i__) {
00560
00561 d__1 = lstres, d__2 = z_abs(&x[i__ + j * x_dim1]);
00562 lstres = max(d__1,d__2);
00563
00564 }
00565 if (lstres != 0.) {
00566 ferr[j] /= lstres;
00567 }
00568
00569
00570 }
00571
00572 return 0;
00573
00574
00575
00576 }