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_b18 = -1.;
00020 static doublereal c_b19 = 1.;
00021
00022 int dgtrfs_(char *trans, integer *n, integer *nrhs,
00023 doublereal *dl, doublereal *d__, doublereal *du, doublereal *dlf,
00024 doublereal *df, doublereal *duf, doublereal *du2, integer *ipiv,
00025 doublereal *b, integer *ldb, doublereal *x, integer *ldx, doublereal *
00026 ferr, doublereal *berr, doublereal *work, integer *iwork, integer *
00027 info)
00028 {
00029
00030 integer b_dim1, b_offset, x_dim1, x_offset, i__1, i__2;
00031 doublereal d__1, d__2, d__3, d__4;
00032
00033
00034 integer i__, j;
00035 doublereal s;
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 dcopy_(integer *, doublereal *, integer *,
00043 doublereal *, integer *), daxpy_(integer *, doublereal *,
00044 doublereal *, integer *, doublereal *, integer *);
00045 integer count;
00046 extern int dlacn2_(integer *, doublereal *, doublereal *,
00047 integer *, doublereal *, integer *, integer *);
00048 extern doublereal dlamch_(char *);
00049 extern int dlagtm_(char *, integer *, integer *,
00050 doublereal *, doublereal *, doublereal *, doublereal *,
00051 doublereal *, integer *, doublereal *, doublereal *, integer *);
00052 doublereal safmin;
00053 extern int xerbla_(char *, integer *);
00054 logical notran;
00055 char transn[1];
00056 extern int dgttrs_(char *, integer *, integer *,
00057 doublereal *, doublereal *, doublereal *, doublereal *, integer *,
00058 doublereal *, integer *, integer *);
00059 char transt[1];
00060 doublereal lstres;
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
00178
00179
00180
00181
00182
00183
00184
00185
00186 --dl;
00187 --d__;
00188 --du;
00189 --dlf;
00190 --df;
00191 --duf;
00192 --du2;
00193 --ipiv;
00194 b_dim1 = *ldb;
00195 b_offset = 1 + b_dim1;
00196 b -= b_offset;
00197 x_dim1 = *ldx;
00198 x_offset = 1 + x_dim1;
00199 x -= x_offset;
00200 --ferr;
00201 --berr;
00202 --work;
00203 --iwork;
00204
00205
00206 *info = 0;
00207 notran = lsame_(trans, "N");
00208 if (! notran && ! lsame_(trans, "T") && ! lsame_(
00209 trans, "C")) {
00210 *info = -1;
00211 } else if (*n < 0) {
00212 *info = -2;
00213 } else if (*nrhs < 0) {
00214 *info = -3;
00215 } else if (*ldb < max(1,*n)) {
00216 *info = -13;
00217 } else if (*ldx < max(1,*n)) {
00218 *info = -15;
00219 }
00220 if (*info != 0) {
00221 i__1 = -(*info);
00222 xerbla_("DGTRFS", &i__1);
00223 return 0;
00224 }
00225
00226
00227
00228 if (*n == 0 || *nrhs == 0) {
00229 i__1 = *nrhs;
00230 for (j = 1; j <= i__1; ++j) {
00231 ferr[j] = 0.;
00232 berr[j] = 0.;
00233
00234 }
00235 return 0;
00236 }
00237
00238 if (notran) {
00239 *(unsigned char *)transn = 'N';
00240 *(unsigned char *)transt = 'T';
00241 } else {
00242 *(unsigned char *)transn = 'T';
00243 *(unsigned char *)transt = 'N';
00244 }
00245
00246
00247
00248 nz = 4;
00249 eps = dlamch_("Epsilon");
00250 safmin = dlamch_("Safe minimum");
00251 safe1 = nz * safmin;
00252 safe2 = safe1 / eps;
00253
00254
00255
00256 i__1 = *nrhs;
00257 for (j = 1; j <= i__1; ++j) {
00258
00259 count = 1;
00260 lstres = 3.;
00261 L20:
00262
00263
00264
00265
00266
00267
00268 dcopy_(n, &b[j * b_dim1 + 1], &c__1, &work[*n + 1], &c__1);
00269 dlagtm_(trans, n, &c__1, &c_b18, &dl[1], &d__[1], &du[1], &x[j *
00270 x_dim1 + 1], ldx, &c_b19, &work[*n + 1], n);
00271
00272
00273
00274
00275 if (notran) {
00276 if (*n == 1) {
00277 work[1] = (d__1 = b[j * b_dim1 + 1], abs(d__1)) + (d__2 = d__[
00278 1] * x[j * x_dim1 + 1], abs(d__2));
00279 } else {
00280 work[1] = (d__1 = b[j * b_dim1 + 1], abs(d__1)) + (d__2 = d__[
00281 1] * x[j * x_dim1 + 1], abs(d__2)) + (d__3 = du[1] *
00282 x[j * x_dim1 + 2], abs(d__3));
00283 i__2 = *n - 1;
00284 for (i__ = 2; i__ <= i__2; ++i__) {
00285 work[i__] = (d__1 = b[i__ + j * b_dim1], abs(d__1)) + (
00286 d__2 = dl[i__ - 1] * x[i__ - 1 + j * x_dim1], abs(
00287 d__2)) + (d__3 = d__[i__] * x[i__ + j * x_dim1],
00288 abs(d__3)) + (d__4 = du[i__] * x[i__ + 1 + j *
00289 x_dim1], abs(d__4));
00290
00291 }
00292 work[*n] = (d__1 = b[*n + j * b_dim1], abs(d__1)) + (d__2 =
00293 dl[*n - 1] * x[*n - 1 + j * x_dim1], abs(d__2)) + (
00294 d__3 = d__[*n] * x[*n + j * x_dim1], abs(d__3));
00295 }
00296 } else {
00297 if (*n == 1) {
00298 work[1] = (d__1 = b[j * b_dim1 + 1], abs(d__1)) + (d__2 = d__[
00299 1] * x[j * x_dim1 + 1], abs(d__2));
00300 } else {
00301 work[1] = (d__1 = b[j * b_dim1 + 1], abs(d__1)) + (d__2 = d__[
00302 1] * x[j * x_dim1 + 1], abs(d__2)) + (d__3 = dl[1] *
00303 x[j * x_dim1 + 2], abs(d__3));
00304 i__2 = *n - 1;
00305 for (i__ = 2; i__ <= i__2; ++i__) {
00306 work[i__] = (d__1 = b[i__ + j * b_dim1], abs(d__1)) + (
00307 d__2 = du[i__ - 1] * x[i__ - 1 + j * x_dim1], abs(
00308 d__2)) + (d__3 = d__[i__] * x[i__ + j * x_dim1],
00309 abs(d__3)) + (d__4 = dl[i__] * x[i__ + 1 + j *
00310 x_dim1], abs(d__4));
00311
00312 }
00313 work[*n] = (d__1 = b[*n + j * b_dim1], abs(d__1)) + (d__2 =
00314 du[*n - 1] * x[*n - 1 + j * x_dim1], abs(d__2)) + (
00315 d__3 = d__[*n] * x[*n + j * x_dim1], abs(d__3));
00316 }
00317 }
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 s = 0.;
00329 i__2 = *n;
00330 for (i__ = 1; i__ <= i__2; ++i__) {
00331 if (work[i__] > safe2) {
00332
00333 d__2 = s, d__3 = (d__1 = work[*n + i__], abs(d__1)) / work[
00334 i__];
00335 s = max(d__2,d__3);
00336 } else {
00337
00338 d__2 = s, d__3 = ((d__1 = work[*n + i__], abs(d__1)) + safe1)
00339 / (work[i__] + safe1);
00340 s = max(d__2,d__3);
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 dgttrs_(trans, n, &c__1, &dlf[1], &df[1], &duf[1], &du2[1], &ipiv[
00357 1], &work[*n + 1], n, info);
00358 daxpy_(n, &c_b19, &work[*n + 1], &c__1, &x[j * x_dim1 + 1], &c__1)
00359 ;
00360 lstres = berr[j];
00361 ++count;
00362 goto L20;
00363 }
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387 i__2 = *n;
00388 for (i__ = 1; i__ <= i__2; ++i__) {
00389 if (work[i__] > safe2) {
00390 work[i__] = (d__1 = work[*n + i__], abs(d__1)) + nz * eps *
00391 work[i__];
00392 } else {
00393 work[i__] = (d__1 = work[*n + i__], abs(d__1)) + nz * eps *
00394 work[i__] + safe1;
00395 }
00396
00397 }
00398
00399 kase = 0;
00400 L70:
00401 dlacn2_(n, &work[(*n << 1) + 1], &work[*n + 1], &iwork[1], &ferr[j], &
00402 kase, isave);
00403 if (kase != 0) {
00404 if (kase == 1) {
00405
00406
00407
00408 dgttrs_(transt, n, &c__1, &dlf[1], &df[1], &duf[1], &du2[1], &
00409 ipiv[1], &work[*n + 1], n, info);
00410 i__2 = *n;
00411 for (i__ = 1; i__ <= i__2; ++i__) {
00412 work[*n + i__] = work[i__] * work[*n + i__];
00413
00414 }
00415 } else {
00416
00417
00418
00419 i__2 = *n;
00420 for (i__ = 1; i__ <= i__2; ++i__) {
00421 work[*n + i__] = work[i__] * work[*n + i__];
00422
00423 }
00424 dgttrs_(transn, n, &c__1, &dlf[1], &df[1], &duf[1], &du2[1], &
00425 ipiv[1], &work[*n + 1], n, info);
00426 }
00427 goto L70;
00428 }
00429
00430
00431
00432 lstres = 0.;
00433 i__2 = *n;
00434 for (i__ = 1; i__ <= i__2; ++i__) {
00435
00436 d__2 = lstres, d__3 = (d__1 = x[i__ + j * x_dim1], abs(d__1));
00437 lstres = max(d__2,d__3);
00438
00439 }
00440 if (lstres != 0.) {
00441 ferr[j] /= lstres;
00442 }
00443
00444
00445 }
00446
00447 return 0;
00448
00449
00450
00451 }