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 dpbrfs_(char *uplo, integer *n, integer *kd, integer *
00023 nrhs, doublereal *ab, integer *ldab, doublereal *afb, integer *ldafb,
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 ab_dim1, ab_offset, afb_dim1, afb_offset, b_dim1, b_offset,
00030 x_dim1, x_offset, i__1, i__2, i__3, i__4, i__5;
00031 doublereal d__1, d__2, d__3;
00032
00033
00034 integer i__, j, k, l;
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 dsbmv_(char *, integer *, integer *,
00043 doublereal *, doublereal *, integer *, doublereal *, integer *,
00044 doublereal *, doublereal *, integer *), dcopy_(integer *,
00045 doublereal *, integer *, doublereal *, integer *), daxpy_(integer
00046 *, doublereal *, doublereal *, integer *, doublereal *, integer *)
00047 ;
00048 integer count;
00049 logical upper;
00050 extern int dlacn2_(integer *, doublereal *, doublereal *,
00051 integer *, doublereal *, integer *, integer *);
00052 extern doublereal dlamch_(char *);
00053 doublereal safmin;
00054 extern int xerbla_(char *, integer *), dpbtrs_(
00055 char *, integer *, integer *, integer *, doublereal *, integer *,
00056 doublereal *, integer *, integer *);
00057 doublereal lstres;
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
00172
00173
00174
00175 ab_dim1 = *ldab;
00176 ab_offset = 1 + ab_dim1;
00177 ab -= ab_offset;
00178 afb_dim1 = *ldafb;
00179 afb_offset = 1 + afb_dim1;
00180 afb -= afb_offset;
00181 b_dim1 = *ldb;
00182 b_offset = 1 + b_dim1;
00183 b -= b_offset;
00184 x_dim1 = *ldx;
00185 x_offset = 1 + x_dim1;
00186 x -= x_offset;
00187 --ferr;
00188 --berr;
00189 --work;
00190 --iwork;
00191
00192
00193 *info = 0;
00194 upper = lsame_(uplo, "U");
00195 if (! upper && ! lsame_(uplo, "L")) {
00196 *info = -1;
00197 } else if (*n < 0) {
00198 *info = -2;
00199 } else if (*kd < 0) {
00200 *info = -3;
00201 } else if (*nrhs < 0) {
00202 *info = -4;
00203 } else if (*ldab < *kd + 1) {
00204 *info = -6;
00205 } else if (*ldafb < *kd + 1) {
00206 *info = -8;
00207 } else if (*ldb < max(1,*n)) {
00208 *info = -10;
00209 } else if (*ldx < max(1,*n)) {
00210 *info = -12;
00211 }
00212 if (*info != 0) {
00213 i__1 = -(*info);
00214 xerbla_("DPBRFS", &i__1);
00215 return 0;
00216 }
00217
00218
00219
00220 if (*n == 0 || *nrhs == 0) {
00221 i__1 = *nrhs;
00222 for (j = 1; j <= i__1; ++j) {
00223 ferr[j] = 0.;
00224 berr[j] = 0.;
00225
00226 }
00227 return 0;
00228 }
00229
00230
00231
00232
00233 i__1 = *n + 1, i__2 = (*kd << 1) + 2;
00234 nz = min(i__1,i__2);
00235 eps = dlamch_("Epsilon");
00236 safmin = dlamch_("Safe minimum");
00237 safe1 = nz * safmin;
00238 safe2 = safe1 / eps;
00239
00240
00241
00242 i__1 = *nrhs;
00243 for (j = 1; j <= i__1; ++j) {
00244
00245 count = 1;
00246 lstres = 3.;
00247 L20:
00248
00249
00250
00251
00252
00253 dcopy_(n, &b[j * b_dim1 + 1], &c__1, &work[*n + 1], &c__1);
00254 dsbmv_(uplo, n, kd, &c_b12, &ab[ab_offset], ldab, &x[j * x_dim1 + 1],
00255 &c__1, &c_b14, &work[*n + 1], &c__1);
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 i__2 = *n;
00267 for (i__ = 1; i__ <= i__2; ++i__) {
00268 work[i__] = (d__1 = b[i__ + j * b_dim1], abs(d__1));
00269
00270 }
00271
00272
00273
00274 if (upper) {
00275 i__2 = *n;
00276 for (k = 1; k <= i__2; ++k) {
00277 s = 0.;
00278 xk = (d__1 = x[k + j * x_dim1], abs(d__1));
00279 l = *kd + 1 - k;
00280
00281 i__3 = 1, i__4 = k - *kd;
00282 i__5 = k - 1;
00283 for (i__ = max(i__3,i__4); i__ <= i__5; ++i__) {
00284 work[i__] += (d__1 = ab[l + i__ + k * ab_dim1], abs(d__1))
00285 * xk;
00286 s += (d__1 = ab[l + i__ + k * ab_dim1], abs(d__1)) * (
00287 d__2 = x[i__ + j * x_dim1], abs(d__2));
00288
00289 }
00290 work[k] = work[k] + (d__1 = ab[*kd + 1 + k * ab_dim1], abs(
00291 d__1)) * xk + s;
00292
00293 }
00294 } else {
00295 i__2 = *n;
00296 for (k = 1; k <= i__2; ++k) {
00297 s = 0.;
00298 xk = (d__1 = x[k + j * x_dim1], abs(d__1));
00299 work[k] += (d__1 = ab[k * ab_dim1 + 1], abs(d__1)) * xk;
00300 l = 1 - k;
00301
00302 i__3 = *n, i__4 = k + *kd;
00303 i__5 = min(i__3,i__4);
00304 for (i__ = k + 1; i__ <= i__5; ++i__) {
00305 work[i__] += (d__1 = ab[l + i__ + k * ab_dim1], abs(d__1))
00306 * xk;
00307 s += (d__1 = ab[l + i__ + k * ab_dim1], abs(d__1)) * (
00308 d__2 = x[i__ + j * x_dim1], abs(d__2));
00309
00310 }
00311 work[k] += s;
00312
00313 }
00314 }
00315 s = 0.;
00316 i__2 = *n;
00317 for (i__ = 1; i__ <= i__2; ++i__) {
00318 if (work[i__] > safe2) {
00319
00320 d__2 = s, d__3 = (d__1 = work[*n + i__], abs(d__1)) / work[
00321 i__];
00322 s = max(d__2,d__3);
00323 } else {
00324
00325 d__2 = s, d__3 = ((d__1 = work[*n + i__], abs(d__1)) + safe1)
00326 / (work[i__] + safe1);
00327 s = max(d__2,d__3);
00328 }
00329
00330 }
00331 berr[j] = s;
00332
00333
00334
00335
00336
00337
00338
00339 if (berr[j] > eps && berr[j] * 2. <= lstres && count <= 5) {
00340
00341
00342
00343 dpbtrs_(uplo, n, kd, &c__1, &afb[afb_offset], ldafb, &work[*n + 1]
00344 , n, info);
00345 daxpy_(n, &c_b14, &work[*n + 1], &c__1, &x[j * x_dim1 + 1], &c__1)
00346 ;
00347 lstres = berr[j];
00348 ++count;
00349 goto L20;
00350 }
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374 i__2 = *n;
00375 for (i__ = 1; i__ <= i__2; ++i__) {
00376 if (work[i__] > safe2) {
00377 work[i__] = (d__1 = work[*n + i__], abs(d__1)) + nz * eps *
00378 work[i__];
00379 } else {
00380 work[i__] = (d__1 = work[*n + i__], abs(d__1)) + nz * eps *
00381 work[i__] + safe1;
00382 }
00383
00384 }
00385
00386 kase = 0;
00387 L100:
00388 dlacn2_(n, &work[(*n << 1) + 1], &work[*n + 1], &iwork[1], &ferr[j], &
00389 kase, isave);
00390 if (kase != 0) {
00391 if (kase == 1) {
00392
00393
00394
00395 dpbtrs_(uplo, n, kd, &c__1, &afb[afb_offset], ldafb, &work[*n
00396 + 1], n, info);
00397 i__2 = *n;
00398 for (i__ = 1; i__ <= i__2; ++i__) {
00399 work[*n + i__] *= work[i__];
00400
00401 }
00402 } else if (kase == 2) {
00403
00404
00405
00406 i__2 = *n;
00407 for (i__ = 1; i__ <= i__2; ++i__) {
00408 work[*n + i__] *= work[i__];
00409
00410 }
00411 dpbtrs_(uplo, n, kd, &c__1, &afb[afb_offset], ldafb, &work[*n
00412 + 1], n, info);
00413 }
00414 goto L100;
00415 }
00416
00417
00418
00419 lstres = 0.;
00420 i__2 = *n;
00421 for (i__ = 1; i__ <= i__2; ++i__) {
00422
00423 d__2 = lstres, d__3 = (d__1 = x[i__ + j * x_dim1], abs(d__1));
00424 lstres = max(d__2,d__3);
00425
00426 }
00427 if (lstres != 0.) {
00428 ferr[j] /= lstres;
00429 }
00430
00431
00432 }
00433
00434 return 0;
00435
00436
00437
00438 }