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