sgbrfs.c
Go to the documentation of this file.
00001 /* sgbrfs.f -- translated by f2c (version 20061008).
00002    You must link the resulting object file with libf2c:
00003         on Microsoft Windows system, link with libf2c.lib;
00004         on Linux or Unix systems, link with .../path/to/libf2c.a -lm
00005         or, if you install libf2c.a in a standard place, with -lf2c -lm
00006         -- in that order, at the end of the command line, as in
00007                 cc *.o -lf2c -lm
00008         Source for libf2c is in /netlib/f2c/libf2c.zip, e.g.,
00009 
00010                 http://www.netlib.org/f2c/libf2c.zip
00011 */
00012 
00013 #include "f2c.h"
00014 #include "blaswrap.h"
00015 
00016 /* Table of constant values */
00017 
00018 static integer c__1 = 1;
00019 static real c_b15 = -1.f;
00020 static real c_b17 = 1.f;
00021 
00022 /* Subroutine */ int sgbrfs_(char *trans, integer *n, integer *kl, integer *
00023         ku, integer *nrhs, real *ab, integer *ldab, real *afb, integer *ldafb, 
00024          integer *ipiv, real *b, integer *ldb, real *x, integer *ldx, real *
00025         ferr, real *berr, real *work, integer *iwork, integer *info)
00026 {
00027     /* System generated locals */
00028     integer ab_dim1, ab_offset, afb_dim1, afb_offset, b_dim1, b_offset, 
00029             x_dim1, x_offset, i__1, i__2, i__3, i__4, i__5, i__6, i__7;
00030     real r__1, r__2, r__3;
00031 
00032     /* Local variables */
00033     integer i__, j, k;
00034     real s;
00035     integer kk;
00036     real xk;
00037     integer nz;
00038     real eps;
00039     integer kase;
00040     real safe1, safe2;
00041     extern logical lsame_(char *, char *);
00042     integer isave[3];
00043     extern /* Subroutine */ int sgbmv_(char *, integer *, integer *, integer *
00044 , integer *, real *, real *, integer *, real *, integer *, real *, 
00045              real *, integer *);
00046     integer count;
00047     extern /* Subroutine */ int scopy_(integer *, real *, integer *, real *, 
00048             integer *), saxpy_(integer *, real *, real *, integer *, real *, 
00049             integer *), slacn2_(integer *, real *, real *, integer *, real *, 
00050             integer *, integer *);
00051     extern doublereal slamch_(char *);
00052     real safmin;
00053     extern /* Subroutine */ int xerbla_(char *, integer *);
00054     logical notran;
00055     extern /* Subroutine */ int sgbtrs_(char *, integer *, integer *, integer 
00056             *, integer *, real *, integer *, integer *, real *, integer *, 
00057             integer *);
00058     char transt[1];
00059     real lstres;
00060 
00061 
00062 /*  -- LAPACK routine (version 3.2) -- */
00063 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00064 /*     November 2006 */
00065 
00066 /*     Modified to call SLACN2 in place of SLACON, 7 Feb 03, SJH. */
00067 
00068 /*     .. Scalar Arguments .. */
00069 /*     .. */
00070 /*     .. Array Arguments .. */
00071 /*     .. */
00072 
00073 /*  Purpose */
00074 /*  ======= */
00075 
00076 /*  SGBRFS improves the computed solution to a system of linear */
00077 /*  equations when the coefficient matrix is banded, and provides */
00078 /*  error bounds and backward error estimates for the solution. */
00079 
00080 /*  Arguments */
00081 /*  ========= */
00082 
00083 /*  TRANS   (input) CHARACTER*1 */
00084 /*          Specifies the form of the system of equations: */
00085 /*          = 'N':  A * X = B     (No transpose) */
00086 /*          = 'T':  A**T * X = B  (Transpose) */
00087 /*          = 'C':  A**H * X = B  (Conjugate transpose = Transpose) */
00088 
00089 /*  N       (input) INTEGER */
00090 /*          The order of the matrix A.  N >= 0. */
00091 
00092 /*  KL      (input) INTEGER */
00093 /*          The number of subdiagonals within the band of A.  KL >= 0. */
00094 
00095 /*  KU      (input) INTEGER */
00096 /*          The number of superdiagonals within the band of A.  KU >= 0. */
00097 
00098 /*  NRHS    (input) INTEGER */
00099 /*          The number of right hand sides, i.e., the number of columns */
00100 /*          of the matrices B and X.  NRHS >= 0. */
00101 
00102 /*  AB      (input) REAL array, dimension (LDAB,N) */
00103 /*          The original band matrix A, stored in rows 1 to KL+KU+1. */
00104 /*          The j-th column of A is stored in the j-th column of the */
00105 /*          array AB as follows: */
00106 /*          AB(ku+1+i-j,j) = A(i,j) for max(1,j-ku)<=i<=min(n,j+kl). */
00107 
00108 /*  LDAB    (input) INTEGER */
00109 /*          The leading dimension of the array AB.  LDAB >= KL+KU+1. */
00110 
00111 /*  AFB     (input) REAL array, dimension (LDAFB,N) */
00112 /*          Details of the LU factorization of the band matrix A, as */
00113 /*          computed by SGBTRF.  U is stored as an upper triangular band */
00114 /*          matrix with KL+KU superdiagonals in rows 1 to KL+KU+1, and */
00115 /*          the multipliers used during the factorization are stored in */
00116 /*          rows KL+KU+2 to 2*KL+KU+1. */
00117 
00118 /*  LDAFB   (input) INTEGER */
00119 /*          The leading dimension of the array AFB.  LDAFB >= 2*KL*KU+1. */
00120 
00121 /*  IPIV    (input) INTEGER array, dimension (N) */
00122 /*          The pivot indices from SGBTRF; for 1<=i<=N, row i of the */
00123 /*          matrix was interchanged with row IPIV(i). */
00124 
00125 /*  B       (input) REAL array, dimension (LDB,NRHS) */
00126 /*          The right hand side matrix B. */
00127 
00128 /*  LDB     (input) INTEGER */
00129 /*          The leading dimension of the array B.  LDB >= max(1,N). */
00130 
00131 /*  X       (input/output) REAL array, dimension (LDX,NRHS) */
00132 /*          On entry, the solution matrix X, as computed by SGBTRS. */
00133 /*          On exit, the improved solution matrix X. */
00134 
00135 /*  LDX     (input) INTEGER */
00136 /*          The leading dimension of the array X.  LDX >= max(1,N). */
00137 
00138 /*  FERR    (output) REAL array, dimension (NRHS) */
00139 /*          The estimated forward error bound for each solution vector */
00140 /*          X(j) (the j-th column of the solution matrix X). */
00141 /*          If XTRUE is the true solution corresponding to X(j), FERR(j) */
00142 /*          is an estimated upper bound for the magnitude of the largest */
00143 /*          element in (X(j) - XTRUE) divided by the magnitude of the */
00144 /*          largest element in X(j).  The estimate is as reliable as */
00145 /*          the estimate for RCOND, and is almost always a slight */
00146 /*          overestimate of the true error. */
00147 
00148 /*  BERR    (output) REAL array, dimension (NRHS) */
00149 /*          The componentwise relative backward error of each solution */
00150 /*          vector X(j) (i.e., the smallest relative change in */
00151 /*          any element of A or B that makes X(j) an exact solution). */
00152 
00153 /*  WORK    (workspace) REAL array, dimension (3*N) */
00154 
00155 /*  IWORK   (workspace) INTEGER array, dimension (N) */
00156 
00157 /*  INFO    (output) INTEGER */
00158 /*          = 0:  successful exit */
00159 /*          < 0:  if INFO = -i, the i-th argument had an illegal value */
00160 
00161 /*  Internal Parameters */
00162 /*  =================== */
00163 
00164 /*  ITMAX is the maximum number of steps of iterative refinement. */
00165 
00166 /*  ===================================================================== */
00167 
00168 /*     .. Parameters .. */
00169 /*     .. */
00170 /*     .. Local Scalars .. */
00171 /*     .. */
00172 /*     .. Local Arrays .. */
00173 /*     .. */
00174 /*     .. External Subroutines .. */
00175 /*     .. */
00176 /*     .. Intrinsic Functions .. */
00177 /*     .. */
00178 /*     .. External Functions .. */
00179 /*     .. */
00180 /*     .. Executable Statements .. */
00181 
00182 /*     Test the input parameters. */
00183 
00184     /* Parameter adjustments */
00185     ab_dim1 = *ldab;
00186     ab_offset = 1 + ab_dim1;
00187     ab -= ab_offset;
00188     afb_dim1 = *ldafb;
00189     afb_offset = 1 + afb_dim1;
00190     afb -= afb_offset;
00191     --ipiv;
00192     b_dim1 = *ldb;
00193     b_offset = 1 + b_dim1;
00194     b -= b_offset;
00195     x_dim1 = *ldx;
00196     x_offset = 1 + x_dim1;
00197     x -= x_offset;
00198     --ferr;
00199     --berr;
00200     --work;
00201     --iwork;
00202 
00203     /* Function Body */
00204     *info = 0;
00205     notran = lsame_(trans, "N");
00206     if (! notran && ! lsame_(trans, "T") && ! lsame_(
00207             trans, "C")) {
00208         *info = -1;
00209     } else if (*n < 0) {
00210         *info = -2;
00211     } else if (*kl < 0) {
00212         *info = -3;
00213     } else if (*ku < 0) {
00214         *info = -4;
00215     } else if (*nrhs < 0) {
00216         *info = -5;
00217     } else if (*ldab < *kl + *ku + 1) {
00218         *info = -7;
00219     } else if (*ldafb < (*kl << 1) + *ku + 1) {
00220         *info = -9;
00221     } else if (*ldb < max(1,*n)) {
00222         *info = -12;
00223     } else if (*ldx < max(1,*n)) {
00224         *info = -14;
00225     }
00226     if (*info != 0) {
00227         i__1 = -(*info);
00228         xerbla_("SGBRFS", &i__1);
00229         return 0;
00230     }
00231 
00232 /*     Quick return if possible */
00233 
00234     if (*n == 0 || *nrhs == 0) {
00235         i__1 = *nrhs;
00236         for (j = 1; j <= i__1; ++j) {
00237             ferr[j] = 0.f;
00238             berr[j] = 0.f;
00239 /* L10: */
00240         }
00241         return 0;
00242     }
00243 
00244     if (notran) {
00245         *(unsigned char *)transt = 'T';
00246     } else {
00247         *(unsigned char *)transt = 'N';
00248     }
00249 
00250 /*     NZ = maximum number of nonzero elements in each row of A, plus 1 */
00251 
00252 /* Computing MIN */
00253     i__1 = *kl + *ku + 2, i__2 = *n + 1;
00254     nz = min(i__1,i__2);
00255     eps = slamch_("Epsilon");
00256     safmin = slamch_("Safe minimum");
00257     safe1 = nz * safmin;
00258     safe2 = safe1 / eps;
00259 
00260 /*     Do for each right hand side */
00261 
00262     i__1 = *nrhs;
00263     for (j = 1; j <= i__1; ++j) {
00264 
00265         count = 1;
00266         lstres = 3.f;
00267 L20:
00268 
00269 /*        Loop until stopping criterion is satisfied. */
00270 
00271 /*        Compute residual R = B - op(A) * X, */
00272 /*        where op(A) = A, A**T, or A**H, depending on TRANS. */
00273 
00274         scopy_(n, &b[j * b_dim1 + 1], &c__1, &work[*n + 1], &c__1);
00275         sgbmv_(trans, n, n, kl, ku, &c_b15, &ab[ab_offset], ldab, &x[j * 
00276                 x_dim1 + 1], &c__1, &c_b17, &work[*n + 1], &c__1);
00277 
00278 /*        Compute componentwise relative backward error from formula */
00279 
00280 /*        max(i) ( abs(R(i)) / ( abs(op(A))*abs(X) + abs(B) )(i) ) */
00281 
00282 /*        where abs(Z) is the componentwise absolute value of the matrix */
00283 /*        or vector Z.  If the i-th component of the denominator is less */
00284 /*        than SAFE2, then SAFE1 is added to the i-th components of the */
00285 /*        numerator and denominator before dividing. */
00286 
00287         i__2 = *n;
00288         for (i__ = 1; i__ <= i__2; ++i__) {
00289             work[i__] = (r__1 = b[i__ + j * b_dim1], dabs(r__1));
00290 /* L30: */
00291         }
00292 
00293 /*        Compute abs(op(A))*abs(X) + abs(B). */
00294 
00295         if (notran) {
00296             i__2 = *n;
00297             for (k = 1; k <= i__2; ++k) {
00298                 kk = *ku + 1 - k;
00299                 xk = (r__1 = x[k + j * x_dim1], dabs(r__1));
00300 /* Computing MAX */
00301                 i__3 = 1, i__4 = k - *ku;
00302 /* Computing MIN */
00303                 i__6 = *n, i__7 = k + *kl;
00304                 i__5 = min(i__6,i__7);
00305                 for (i__ = max(i__3,i__4); i__ <= i__5; ++i__) {
00306                     work[i__] += (r__1 = ab[kk + i__ + k * ab_dim1], dabs(
00307                             r__1)) * xk;
00308 /* L40: */
00309                 }
00310 /* L50: */
00311             }
00312         } else {
00313             i__2 = *n;
00314             for (k = 1; k <= i__2; ++k) {
00315                 s = 0.f;
00316                 kk = *ku + 1 - k;
00317 /* Computing MAX */
00318                 i__5 = 1, i__3 = k - *ku;
00319 /* Computing MIN */
00320                 i__6 = *n, i__7 = k + *kl;
00321                 i__4 = min(i__6,i__7);
00322                 for (i__ = max(i__5,i__3); i__ <= i__4; ++i__) {
00323                     s += (r__1 = ab[kk + i__ + k * ab_dim1], dabs(r__1)) * (
00324                             r__2 = x[i__ + j * x_dim1], dabs(r__2));
00325 /* L60: */
00326                 }
00327                 work[k] += s;
00328 /* L70: */
00329             }
00330         }
00331         s = 0.f;
00332         i__2 = *n;
00333         for (i__ = 1; i__ <= i__2; ++i__) {
00334             if (work[i__] > safe2) {
00335 /* Computing MAX */
00336                 r__2 = s, r__3 = (r__1 = work[*n + i__], dabs(r__1)) / work[
00337                         i__];
00338                 s = dmax(r__2,r__3);
00339             } else {
00340 /* Computing MAX */
00341                 r__2 = s, r__3 = ((r__1 = work[*n + i__], dabs(r__1)) + safe1)
00342                          / (work[i__] + safe1);
00343                 s = dmax(r__2,r__3);
00344             }
00345 /* L80: */
00346         }
00347         berr[j] = s;
00348 
00349 /*        Test stopping criterion. Continue iterating if */
00350 /*           1) The residual BERR(J) is larger than machine epsilon, and */
00351 /*           2) BERR(J) decreased by at least a factor of 2 during the */
00352 /*              last iteration, and */
00353 /*           3) At most ITMAX iterations tried. */
00354 
00355         if (berr[j] > eps && berr[j] * 2.f <= lstres && count <= 5) {
00356 
00357 /*           Update solution and try again. */
00358 
00359             sgbtrs_(trans, n, kl, ku, &c__1, &afb[afb_offset], ldafb, &ipiv[1]
00360 , &work[*n + 1], n, info);
00361             saxpy_(n, &c_b17, &work[*n + 1], &c__1, &x[j * x_dim1 + 1], &c__1)
00362                     ;
00363             lstres = berr[j];
00364             ++count;
00365             goto L20;
00366         }
00367 
00368 /*        Bound error from formula */
00369 
00370 /*        norm(X - XTRUE) / norm(X) .le. FERR = */
00371 /*        norm( abs(inv(op(A)))* */
00372 /*           ( abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) / norm(X) */
00373 
00374 /*        where */
00375 /*          norm(Z) is the magnitude of the largest component of Z */
00376 /*          inv(op(A)) is the inverse of op(A) */
00377 /*          abs(Z) is the componentwise absolute value of the matrix or */
00378 /*             vector Z */
00379 /*          NZ is the maximum number of nonzeros in any row of A, plus 1 */
00380 /*          EPS is machine epsilon */
00381 
00382 /*        The i-th component of abs(R)+NZ*EPS*(abs(op(A))*abs(X)+abs(B)) */
00383 /*        is incremented by SAFE1 if the i-th component of */
00384 /*        abs(op(A))*abs(X) + abs(B) is less than SAFE2. */
00385 
00386 /*        Use SLACN2 to estimate the infinity-norm of the matrix */
00387 /*           inv(op(A)) * diag(W), */
00388 /*        where W = abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) */
00389 
00390         i__2 = *n;
00391         for (i__ = 1; i__ <= i__2; ++i__) {
00392             if (work[i__] > safe2) {
00393                 work[i__] = (r__1 = work[*n + i__], dabs(r__1)) + nz * eps * 
00394                         work[i__];
00395             } else {
00396                 work[i__] = (r__1 = work[*n + i__], dabs(r__1)) + nz * eps * 
00397                         work[i__] + safe1;
00398             }
00399 /* L90: */
00400         }
00401 
00402         kase = 0;
00403 L100:
00404         slacn2_(n, &work[(*n << 1) + 1], &work[*n + 1], &iwork[1], &ferr[j], &
00405                 kase, isave);
00406         if (kase != 0) {
00407             if (kase == 1) {
00408 
00409 /*              Multiply by diag(W)*inv(op(A)**T). */
00410 
00411                 sgbtrs_(transt, n, kl, ku, &c__1, &afb[afb_offset], ldafb, &
00412                         ipiv[1], &work[*n + 1], n, info);
00413                 i__2 = *n;
00414                 for (i__ = 1; i__ <= i__2; ++i__) {
00415                     work[*n + i__] *= work[i__];
00416 /* L110: */
00417                 }
00418             } else {
00419 
00420 /*              Multiply by inv(op(A))*diag(W). */
00421 
00422                 i__2 = *n;
00423                 for (i__ = 1; i__ <= i__2; ++i__) {
00424                     work[*n + i__] *= work[i__];
00425 /* L120: */
00426                 }
00427                 sgbtrs_(trans, n, kl, ku, &c__1, &afb[afb_offset], ldafb, &
00428                         ipiv[1], &work[*n + 1], n, info);
00429             }
00430             goto L100;
00431         }
00432 
00433 /*        Normalize error. */
00434 
00435         lstres = 0.f;
00436         i__2 = *n;
00437         for (i__ = 1; i__ <= i__2; ++i__) {
00438 /* Computing MAX */
00439             r__2 = lstres, r__3 = (r__1 = x[i__ + j * x_dim1], dabs(r__1));
00440             lstres = dmax(r__2,r__3);
00441 /* L130: */
00442         }
00443         if (lstres != 0.f) {
00444             ferr[j] /= lstres;
00445         }
00446 
00447 /* L140: */
00448     }
00449 
00450     return 0;
00451 
00452 /*     End of SGBRFS */
00453 
00454 } /* sgbrfs_ */


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:56:05