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 zgbrfs_(char *trans, integer *n, integer *kl, integer *
00022 ku, integer *nrhs, doublecomplex *ab, integer *ldab, doublecomplex *
00023 afb, integer *ldafb, integer *ipiv, doublecomplex *b, integer *ldb,
00024 doublecomplex *x, integer *ldx, doublereal *ferr, doublereal *berr,
00025 doublecomplex *work, doublereal *rwork, integer *info)
00026 {
00027
00028 integer ab_dim1, ab_offset, afb_dim1, afb_offset, b_dim1, b_offset,
00029 x_dim1, x_offset, i__1, i__2, i__3, i__4, i__5, i__6, i__7;
00030 doublereal d__1, d__2, d__3, d__4;
00031 doublecomplex z__1;
00032
00033
00034 double d_imag(doublecomplex *);
00035
00036
00037 integer i__, j, k;
00038 doublereal s;
00039 integer kk;
00040 doublereal xk;
00041 integer nz;
00042 doublereal eps;
00043 integer kase;
00044 doublereal safe1, safe2;
00045 extern logical lsame_(char *, char *);
00046 integer isave[3];
00047 extern int zgbmv_(char *, integer *, integer *, integer *
00048 , integer *, doublecomplex *, doublecomplex *, integer *,
00049 doublecomplex *, integer *, doublecomplex *, doublecomplex *,
00050 integer *);
00051 integer count;
00052 extern int zcopy_(integer *, doublecomplex *, integer *,
00053 doublecomplex *, integer *), zaxpy_(integer *, doublecomplex *,
00054 doublecomplex *, integer *, doublecomplex *, integer *), zlacn2_(
00055 integer *, doublecomplex *, doublecomplex *, doublereal *,
00056 integer *, integer *);
00057 extern doublereal dlamch_(char *);
00058 doublereal safmin;
00059 extern int xerbla_(char *, integer *);
00060 logical notran;
00061 char transn[1], transt[1];
00062 doublereal lstres;
00063 extern int zgbtrs_(char *, integer *, integer *, integer
00064 *, integer *, doublecomplex *, integer *, integer *,
00065 doublecomplex *, integer *, integer *);
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
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195 ab_dim1 = *ldab;
00196 ab_offset = 1 + ab_dim1;
00197 ab -= ab_offset;
00198 afb_dim1 = *ldafb;
00199 afb_offset = 1 + afb_dim1;
00200 afb -= afb_offset;
00201 --ipiv;
00202 b_dim1 = *ldb;
00203 b_offset = 1 + b_dim1;
00204 b -= b_offset;
00205 x_dim1 = *ldx;
00206 x_offset = 1 + x_dim1;
00207 x -= x_offset;
00208 --ferr;
00209 --berr;
00210 --work;
00211 --rwork;
00212
00213
00214 *info = 0;
00215 notran = lsame_(trans, "N");
00216 if (! notran && ! lsame_(trans, "T") && ! lsame_(
00217 trans, "C")) {
00218 *info = -1;
00219 } else if (*n < 0) {
00220 *info = -2;
00221 } else if (*kl < 0) {
00222 *info = -3;
00223 } else if (*ku < 0) {
00224 *info = -4;
00225 } else if (*nrhs < 0) {
00226 *info = -5;
00227 } else if (*ldab < *kl + *ku + 1) {
00228 *info = -7;
00229 } else if (*ldafb < (*kl << 1) + *ku + 1) {
00230 *info = -9;
00231 } else if (*ldb < max(1,*n)) {
00232 *info = -12;
00233 } else if (*ldx < max(1,*n)) {
00234 *info = -14;
00235 }
00236 if (*info != 0) {
00237 i__1 = -(*info);
00238 xerbla_("ZGBRFS", &i__1);
00239 return 0;
00240 }
00241
00242
00243
00244 if (*n == 0 || *nrhs == 0) {
00245 i__1 = *nrhs;
00246 for (j = 1; j <= i__1; ++j) {
00247 ferr[j] = 0.;
00248 berr[j] = 0.;
00249
00250 }
00251 return 0;
00252 }
00253
00254 if (notran) {
00255 *(unsigned char *)transn = 'N';
00256 *(unsigned char *)transt = 'C';
00257 } else {
00258 *(unsigned char *)transn = 'C';
00259 *(unsigned char *)transt = 'N';
00260 }
00261
00262
00263
00264
00265 i__1 = *kl + *ku + 2, i__2 = *n + 1;
00266 nz = min(i__1,i__2);
00267 eps = dlamch_("Epsilon");
00268 safmin = dlamch_("Safe minimum");
00269 safe1 = nz * safmin;
00270 safe2 = safe1 / eps;
00271
00272
00273
00274 i__1 = *nrhs;
00275 for (j = 1; j <= i__1; ++j) {
00276
00277 count = 1;
00278 lstres = 3.;
00279 L20:
00280
00281
00282
00283
00284
00285
00286 zcopy_(n, &b[j * b_dim1 + 1], &c__1, &work[1], &c__1);
00287 z__1.r = -1., z__1.i = -0.;
00288 zgbmv_(trans, n, n, kl, ku, &z__1, &ab[ab_offset], ldab, &x[j *
00289 x_dim1 + 1], &c__1, &c_b1, &work[1], &c__1);
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 i__2 = *n;
00301 for (i__ = 1; i__ <= i__2; ++i__) {
00302 i__3 = i__ + j * b_dim1;
00303 rwork[i__] = (d__1 = b[i__3].r, abs(d__1)) + (d__2 = d_imag(&b[
00304 i__ + j * b_dim1]), abs(d__2));
00305
00306 }
00307
00308
00309
00310 if (notran) {
00311 i__2 = *n;
00312 for (k = 1; k <= i__2; ++k) {
00313 kk = *ku + 1 - k;
00314 i__3 = k + j * x_dim1;
00315 xk = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(&x[k + j *
00316 x_dim1]), abs(d__2));
00317
00318 i__3 = 1, i__4 = k - *ku;
00319
00320 i__6 = *n, i__7 = k + *kl;
00321 i__5 = min(i__6,i__7);
00322 for (i__ = max(i__3,i__4); i__ <= i__5; ++i__) {
00323 i__3 = kk + i__ + k * ab_dim1;
00324 rwork[i__] += ((d__1 = ab[i__3].r, abs(d__1)) + (d__2 =
00325 d_imag(&ab[kk + i__ + k * ab_dim1]), abs(d__2))) *
00326 xk;
00327
00328 }
00329
00330 }
00331 } else {
00332 i__2 = *n;
00333 for (k = 1; k <= i__2; ++k) {
00334 s = 0.;
00335 kk = *ku + 1 - k;
00336
00337 i__5 = 1, i__3 = k - *ku;
00338
00339 i__6 = *n, i__7 = k + *kl;
00340 i__4 = min(i__6,i__7);
00341 for (i__ = max(i__5,i__3); i__ <= i__4; ++i__) {
00342 i__5 = kk + i__ + k * ab_dim1;
00343 i__3 = i__ + j * x_dim1;
00344 s += ((d__1 = ab[i__5].r, abs(d__1)) + (d__2 = d_imag(&ab[
00345 kk + i__ + k * ab_dim1]), abs(d__2))) * ((d__3 =
00346 x[i__3].r, abs(d__3)) + (d__4 = d_imag(&x[i__ + j
00347 * x_dim1]), abs(d__4)));
00348
00349 }
00350 rwork[k] += s;
00351
00352 }
00353 }
00354 s = 0.;
00355 i__2 = *n;
00356 for (i__ = 1; i__ <= i__2; ++i__) {
00357 if (rwork[i__] > safe2) {
00358
00359 i__4 = i__;
00360 d__3 = s, d__4 = ((d__1 = work[i__4].r, abs(d__1)) + (d__2 =
00361 d_imag(&work[i__]), abs(d__2))) / rwork[i__];
00362 s = max(d__3,d__4);
00363 } else {
00364
00365 i__4 = i__;
00366 d__3 = s, d__4 = ((d__1 = work[i__4].r, abs(d__1)) + (d__2 =
00367 d_imag(&work[i__]), abs(d__2)) + safe1) / (rwork[i__]
00368 + safe1);
00369 s = max(d__3,d__4);
00370 }
00371
00372 }
00373 berr[j] = s;
00374
00375
00376
00377
00378
00379
00380
00381 if (berr[j] > eps && berr[j] * 2. <= lstres && count <= 5) {
00382
00383
00384
00385 zgbtrs_(trans, n, kl, ku, &c__1, &afb[afb_offset], ldafb, &ipiv[1]
00386 , &work[1], n, info);
00387 zaxpy_(n, &c_b1, &work[1], &c__1, &x[j * x_dim1 + 1], &c__1);
00388 lstres = berr[j];
00389 ++count;
00390 goto L20;
00391 }
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415 i__2 = *n;
00416 for (i__ = 1; i__ <= i__2; ++i__) {
00417 if (rwork[i__] > safe2) {
00418 i__4 = i__;
00419 rwork[i__] = (d__1 = work[i__4].r, abs(d__1)) + (d__2 =
00420 d_imag(&work[i__]), abs(d__2)) + nz * eps * rwork[i__]
00421 ;
00422 } else {
00423 i__4 = i__;
00424 rwork[i__] = (d__1 = work[i__4].r, abs(d__1)) + (d__2 =
00425 d_imag(&work[i__]), abs(d__2)) + nz * eps * rwork[i__]
00426 + safe1;
00427 }
00428
00429 }
00430
00431 kase = 0;
00432 L100:
00433 zlacn2_(n, &work[*n + 1], &work[1], &ferr[j], &kase, isave);
00434 if (kase != 0) {
00435 if (kase == 1) {
00436
00437
00438
00439 zgbtrs_(transt, n, kl, ku, &c__1, &afb[afb_offset], ldafb, &
00440 ipiv[1], &work[1], n, info);
00441 i__2 = *n;
00442 for (i__ = 1; i__ <= i__2; ++i__) {
00443 i__4 = i__;
00444 i__5 = i__;
00445 i__3 = i__;
00446 z__1.r = rwork[i__5] * work[i__3].r, z__1.i = rwork[i__5]
00447 * work[i__3].i;
00448 work[i__4].r = z__1.r, work[i__4].i = z__1.i;
00449
00450 }
00451 } else {
00452
00453
00454
00455 i__2 = *n;
00456 for (i__ = 1; i__ <= i__2; ++i__) {
00457 i__4 = i__;
00458 i__5 = i__;
00459 i__3 = i__;
00460 z__1.r = rwork[i__5] * work[i__3].r, z__1.i = rwork[i__5]
00461 * work[i__3].i;
00462 work[i__4].r = z__1.r, work[i__4].i = z__1.i;
00463
00464 }
00465 zgbtrs_(transn, n, kl, ku, &c__1, &afb[afb_offset], ldafb, &
00466 ipiv[1], &work[1], n, info);
00467 }
00468 goto L100;
00469 }
00470
00471
00472
00473 lstres = 0.;
00474 i__2 = *n;
00475 for (i__ = 1; i__ <= i__2; ++i__) {
00476
00477 i__4 = i__ + j * x_dim1;
00478 d__3 = lstres, d__4 = (d__1 = x[i__4].r, abs(d__1)) + (d__2 =
00479 d_imag(&x[i__ + j * x_dim1]), abs(d__2));
00480 lstres = max(d__3,d__4);
00481
00482 }
00483 if (lstres != 0.) {
00484 ferr[j] /= lstres;
00485 }
00486
00487
00488 }
00489
00490 return 0;
00491
00492
00493
00494 }