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 real c_b11 = 1.f;
00020
00021 int sptrfs_(integer *n, integer *nrhs, real *d__, real *e,
00022 real *df, real *ef, real *b, integer *ldb, real *x, integer *ldx,
00023 real *ferr, real *berr, real *work, integer *info)
00024 {
00025
00026 integer b_dim1, b_offset, x_dim1, x_offset, i__1, i__2;
00027 real r__1, r__2, r__3;
00028
00029
00030 integer i__, j;
00031 real s, bi, cx, dx, ex;
00032 integer ix, nz;
00033 real eps, safe1, safe2;
00034 integer count;
00035 extern int saxpy_(integer *, real *, real *, integer *,
00036 real *, integer *);
00037 extern doublereal slamch_(char *);
00038 real safmin;
00039 extern int xerbla_(char *, integer *);
00040 extern integer isamax_(integer *, real *, integer *);
00041 real lstres;
00042 extern int spttrs_(integer *, integer *, real *, real *,
00043 real *, integer *, integer *);
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
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 --d__;
00142 --e;
00143 --df;
00144 --ef;
00145 b_dim1 = *ldb;
00146 b_offset = 1 + b_dim1;
00147 b -= b_offset;
00148 x_dim1 = *ldx;
00149 x_offset = 1 + x_dim1;
00150 x -= x_offset;
00151 --ferr;
00152 --berr;
00153 --work;
00154
00155
00156 *info = 0;
00157 if (*n < 0) {
00158 *info = -1;
00159 } else if (*nrhs < 0) {
00160 *info = -2;
00161 } else if (*ldb < max(1,*n)) {
00162 *info = -8;
00163 } else if (*ldx < max(1,*n)) {
00164 *info = -10;
00165 }
00166 if (*info != 0) {
00167 i__1 = -(*info);
00168 xerbla_("SPTRFS", &i__1);
00169 return 0;
00170 }
00171
00172
00173
00174 if (*n == 0 || *nrhs == 0) {
00175 i__1 = *nrhs;
00176 for (j = 1; j <= i__1; ++j) {
00177 ferr[j] = 0.f;
00178 berr[j] = 0.f;
00179
00180 }
00181 return 0;
00182 }
00183
00184
00185
00186 nz = 4;
00187 eps = slamch_("Epsilon");
00188 safmin = slamch_("Safe minimum");
00189 safe1 = nz * safmin;
00190 safe2 = safe1 / eps;
00191
00192
00193
00194 i__1 = *nrhs;
00195 for (j = 1; j <= i__1; ++j) {
00196
00197 count = 1;
00198 lstres = 3.f;
00199 L20:
00200
00201
00202
00203
00204
00205
00206 if (*n == 1) {
00207 bi = b[j * b_dim1 + 1];
00208 dx = d__[1] * x[j * x_dim1 + 1];
00209 work[*n + 1] = bi - dx;
00210 work[1] = dabs(bi) + dabs(dx);
00211 } else {
00212 bi = b[j * b_dim1 + 1];
00213 dx = d__[1] * x[j * x_dim1 + 1];
00214 ex = e[1] * x[j * x_dim1 + 2];
00215 work[*n + 1] = bi - dx - ex;
00216 work[1] = dabs(bi) + dabs(dx) + dabs(ex);
00217 i__2 = *n - 1;
00218 for (i__ = 2; i__ <= i__2; ++i__) {
00219 bi = b[i__ + j * b_dim1];
00220 cx = e[i__ - 1] * x[i__ - 1 + j * x_dim1];
00221 dx = d__[i__] * x[i__ + j * x_dim1];
00222 ex = e[i__] * x[i__ + 1 + j * x_dim1];
00223 work[*n + i__] = bi - cx - dx - ex;
00224 work[i__] = dabs(bi) + dabs(cx) + dabs(dx) + dabs(ex);
00225
00226 }
00227 bi = b[*n + j * b_dim1];
00228 cx = e[*n - 1] * x[*n - 1 + j * x_dim1];
00229 dx = d__[*n] * x[*n + j * x_dim1];
00230 work[*n + *n] = bi - cx - dx;
00231 work[*n] = dabs(bi) + dabs(cx) + dabs(dx);
00232 }
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243 s = 0.f;
00244 i__2 = *n;
00245 for (i__ = 1; i__ <= i__2; ++i__) {
00246 if (work[i__] > safe2) {
00247
00248 r__2 = s, r__3 = (r__1 = work[*n + i__], dabs(r__1)) / work[
00249 i__];
00250 s = dmax(r__2,r__3);
00251 } else {
00252
00253 r__2 = s, r__3 = ((r__1 = work[*n + i__], dabs(r__1)) + safe1)
00254 / (work[i__] + safe1);
00255 s = dmax(r__2,r__3);
00256 }
00257
00258 }
00259 berr[j] = s;
00260
00261
00262
00263
00264
00265
00266
00267 if (berr[j] > eps && berr[j] * 2.f <= lstres && count <= 5) {
00268
00269
00270
00271 spttrs_(n, &c__1, &df[1], &ef[1], &work[*n + 1], n, info);
00272 saxpy_(n, &c_b11, &work[*n + 1], &c__1, &x[j * x_dim1 + 1], &c__1)
00273 ;
00274 lstres = berr[j];
00275 ++count;
00276 goto L20;
00277 }
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297 i__2 = *n;
00298 for (i__ = 1; i__ <= i__2; ++i__) {
00299 if (work[i__] > safe2) {
00300 work[i__] = (r__1 = work[*n + i__], dabs(r__1)) + nz * eps *
00301 work[i__];
00302 } else {
00303 work[i__] = (r__1 = work[*n + i__], dabs(r__1)) + nz * eps *
00304 work[i__] + safe1;
00305 }
00306
00307 }
00308 ix = isamax_(n, &work[1], &c__1);
00309 ferr[j] = work[ix];
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322 work[1] = 1.f;
00323 i__2 = *n;
00324 for (i__ = 2; i__ <= i__2; ++i__) {
00325 work[i__] = work[i__ - 1] * (r__1 = ef[i__ - 1], dabs(r__1)) +
00326 1.f;
00327
00328 }
00329
00330
00331
00332 work[*n] /= df[*n];
00333 for (i__ = *n - 1; i__ >= 1; --i__) {
00334 work[i__] = work[i__] / df[i__] + work[i__ + 1] * (r__1 = ef[i__],
00335 dabs(r__1));
00336
00337 }
00338
00339
00340
00341 ix = isamax_(n, &work[1], &c__1);
00342 ferr[j] *= (r__1 = work[ix], dabs(r__1));
00343
00344
00345
00346 lstres = 0.f;
00347 i__2 = *n;
00348 for (i__ = 1; i__ <= i__2; ++i__) {
00349
00350 r__2 = lstres, r__3 = (r__1 = x[i__ + j * x_dim1], dabs(r__1));
00351 lstres = dmax(r__2,r__3);
00352
00353 }
00354 if (lstres != 0.f) {
00355 ferr[j] /= lstres;
00356 }
00357
00358
00359 }
00360
00361 return 0;
00362
00363
00364
00365 }