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