cpbrfs.c
Go to the documentation of this file.
00001 /* cpbrfs.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 complex c_b1 = {1.f,0.f};
00019 static integer c__1 = 1;
00020 
00021 /* Subroutine */ int cpbrfs_(char *uplo, integer *n, integer *kd, integer *
00022         nrhs, complex *ab, integer *ldab, complex *afb, integer *ldafb, 
00023         complex *b, integer *ldb, complex *x, integer *ldx, real *ferr, real *
00024         berr, complex *work, real *rwork, integer *info)
00025 {
00026     /* System generated locals */
00027     integer ab_dim1, ab_offset, afb_dim1, afb_offset, b_dim1, b_offset, 
00028             x_dim1, x_offset, i__1, i__2, i__3, i__4, i__5;
00029     real r__1, r__2, r__3, r__4;
00030     complex q__1;
00031 
00032     /* Builtin functions */
00033     double r_imag(complex *);
00034 
00035     /* Local variables */
00036     integer i__, j, k, l;
00037     real s, xk;
00038     integer nz;
00039     real eps;
00040     integer kase;
00041     real safe1, safe2;
00042     extern /* Subroutine */ int chbmv_(char *, integer *, integer *, complex *
00043 , complex *, integer *, complex *, integer *, complex *, complex *
00044 , integer *);
00045     extern logical lsame_(char *, char *);
00046     integer isave[3];
00047     extern /* Subroutine */ int ccopy_(integer *, complex *, integer *, 
00048             complex *, integer *), caxpy_(integer *, complex *, complex *, 
00049             integer *, complex *, integer *);
00050     integer count;
00051     logical upper;
00052     extern /* Subroutine */ int clacn2_(integer *, complex *, complex *, real 
00053             *, integer *, integer *);
00054     extern doublereal slamch_(char *);
00055     real safmin;
00056     extern /* Subroutine */ int xerbla_(char *, integer *), cpbtrs_(
00057             char *, integer *, integer *, integer *, complex *, integer *, 
00058             complex *, integer *, integer *);
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 CLACN2 in place of CLACON, 10 Feb 03, SJH. */
00067 
00068 /*     .. Scalar Arguments .. */
00069 /*     .. */
00070 /*     .. Array Arguments .. */
00071 /*     .. */
00072 
00073 /*  Purpose */
00074 /*  ======= */
00075 
00076 /*  CPBRFS improves the computed solution to a system of linear */
00077 /*  equations when the coefficient matrix is Hermitian positive definite */
00078 /*  and banded, and provides error bounds and backward error estimates */
00079 /*  for the solution. */
00080 
00081 /*  Arguments */
00082 /*  ========= */
00083 
00084 /*  UPLO    (input) CHARACTER*1 */
00085 /*          = 'U':  Upper triangle of A is stored; */
00086 /*          = 'L':  Lower triangle of A is stored. */
00087 
00088 /*  N       (input) INTEGER */
00089 /*          The order of the matrix A.  N >= 0. */
00090 
00091 /*  KD      (input) INTEGER */
00092 /*          The number of superdiagonals of the matrix A if UPLO = 'U', */
00093 /*          or the number of subdiagonals if UPLO = 'L'.  KD >= 0. */
00094 
00095 /*  NRHS    (input) INTEGER */
00096 /*          The number of right hand sides, i.e., the number of columns */
00097 /*          of the matrices B and X.  NRHS >= 0. */
00098 
00099 /*  AB      (input) COMPLEX array, dimension (LDAB,N) */
00100 /*          The upper or lower triangle of the Hermitian band matrix A, */
00101 /*          stored in the first KD+1 rows of the array.  The j-th column */
00102 /*          of A is stored in the j-th column of the array AB as follows: */
00103 /*          if UPLO = 'U', AB(kd+1+i-j,j) = A(i,j) for max(1,j-kd)<=i<=j; */
00104 /*          if UPLO = 'L', AB(1+i-j,j)    = A(i,j) for j<=i<=min(n,j+kd). */
00105 
00106 /*  LDAB    (input) INTEGER */
00107 /*          The leading dimension of the array AB.  LDAB >= KD+1. */
00108 
00109 /*  AFB     (input) COMPLEX array, dimension (LDAFB,N) */
00110 /*          The triangular factor U or L from the Cholesky factorization */
00111 /*          A = U**H*U or A = L*L**H of the band matrix A as computed by */
00112 /*          CPBTRF, in the same storage format as A (see AB). */
00113 
00114 /*  LDAFB   (input) INTEGER */
00115 /*          The leading dimension of the array AFB.  LDAFB >= KD+1. */
00116 
00117 /*  B       (input) COMPLEX array, dimension (LDB,NRHS) */
00118 /*          The right hand side matrix B. */
00119 
00120 /*  LDB     (input) INTEGER */
00121 /*          The leading dimension of the array B.  LDB >= max(1,N). */
00122 
00123 /*  X       (input/output) COMPLEX array, dimension (LDX,NRHS) */
00124 /*          On entry, the solution matrix X, as computed by CPBTRS. */
00125 /*          On exit, the improved solution matrix X. */
00126 
00127 /*  LDX     (input) INTEGER */
00128 /*          The leading dimension of the array X.  LDX >= max(1,N). */
00129 
00130 /*  FERR    (output) REAL array, dimension (NRHS) */
00131 /*          The estimated forward error bound for each solution vector */
00132 /*          X(j) (the j-th column of the solution matrix X). */
00133 /*          If XTRUE is the true solution corresponding to X(j), FERR(j) */
00134 /*          is an estimated upper bound for the magnitude of the largest */
00135 /*          element in (X(j) - XTRUE) divided by the magnitude of the */
00136 /*          largest element in X(j).  The estimate is as reliable as */
00137 /*          the estimate for RCOND, and is almost always a slight */
00138 /*          overestimate of the true error. */
00139 
00140 /*  BERR    (output) REAL array, dimension (NRHS) */
00141 /*          The componentwise relative backward error of each solution */
00142 /*          vector X(j) (i.e., the smallest relative change in */
00143 /*          any element of A or B that makes X(j) an exact solution). */
00144 
00145 /*  WORK    (workspace) COMPLEX array, dimension (2*N) */
00146 
00147 /*  RWORK   (workspace) REAL array, dimension (N) */
00148 
00149 /*  INFO    (output) INTEGER */
00150 /*          = 0:  successful exit */
00151 /*          < 0:  if INFO = -i, the i-th argument had an illegal value */
00152 
00153 /*  Internal Parameters */
00154 /*  =================== */
00155 
00156 /*  ITMAX is the maximum number of steps of iterative refinement. */
00157 
00158 /*  ===================================================================== */
00159 
00160 /*     .. Parameters .. */
00161 /*     .. */
00162 /*     .. Local Scalars .. */
00163 /*     .. */
00164 /*     .. Local Arrays .. */
00165 /*     .. */
00166 /*     .. External Subroutines .. */
00167 /*     .. */
00168 /*     .. Intrinsic Functions .. */
00169 /*     .. */
00170 /*     .. External Functions .. */
00171 /*     .. */
00172 /*     .. Statement Functions .. */
00173 /*     .. */
00174 /*     .. Statement Function definitions .. */
00175 /*     .. */
00176 /*     .. Executable Statements .. */
00177 
00178 /*     Test the input parameters. */
00179 
00180     /* Parameter adjustments */
00181     ab_dim1 = *ldab;
00182     ab_offset = 1 + ab_dim1;
00183     ab -= ab_offset;
00184     afb_dim1 = *ldafb;
00185     afb_offset = 1 + afb_dim1;
00186     afb -= afb_offset;
00187     b_dim1 = *ldb;
00188     b_offset = 1 + b_dim1;
00189     b -= b_offset;
00190     x_dim1 = *ldx;
00191     x_offset = 1 + x_dim1;
00192     x -= x_offset;
00193     --ferr;
00194     --berr;
00195     --work;
00196     --rwork;
00197 
00198     /* Function Body */
00199     *info = 0;
00200     upper = lsame_(uplo, "U");
00201     if (! upper && ! lsame_(uplo, "L")) {
00202         *info = -1;
00203     } else if (*n < 0) {
00204         *info = -2;
00205     } else if (*kd < 0) {
00206         *info = -3;
00207     } else if (*nrhs < 0) {
00208         *info = -4;
00209     } else if (*ldab < *kd + 1) {
00210         *info = -6;
00211     } else if (*ldafb < *kd + 1) {
00212         *info = -8;
00213     } else if (*ldb < max(1,*n)) {
00214         *info = -10;
00215     } else if (*ldx < max(1,*n)) {
00216         *info = -12;
00217     }
00218     if (*info != 0) {
00219         i__1 = -(*info);
00220         xerbla_("CPBRFS", &i__1);
00221         return 0;
00222     }
00223 
00224 /*     Quick return if possible */
00225 
00226     if (*n == 0 || *nrhs == 0) {
00227         i__1 = *nrhs;
00228         for (j = 1; j <= i__1; ++j) {
00229             ferr[j] = 0.f;
00230             berr[j] = 0.f;
00231 /* L10: */
00232         }
00233         return 0;
00234     }
00235 
00236 /*     NZ = maximum number of nonzero elements in each row of A, plus 1 */
00237 
00238 /* Computing MIN */
00239     i__1 = *n + 1, i__2 = (*kd << 1) + 2;
00240     nz = min(i__1,i__2);
00241     eps = slamch_("Epsilon");
00242     safmin = slamch_("Safe minimum");
00243     safe1 = nz * safmin;
00244     safe2 = safe1 / eps;
00245 
00246 /*     Do for each right hand side */
00247 
00248     i__1 = *nrhs;
00249     for (j = 1; j <= i__1; ++j) {
00250 
00251         count = 1;
00252         lstres = 3.f;
00253 L20:
00254 
00255 /*        Loop until stopping criterion is satisfied. */
00256 
00257 /*        Compute residual R = B - A * X */
00258 
00259         ccopy_(n, &b[j * b_dim1 + 1], &c__1, &work[1], &c__1);
00260         q__1.r = -1.f, q__1.i = -0.f;
00261         chbmv_(uplo, n, kd, &q__1, &ab[ab_offset], ldab, &x[j * x_dim1 + 1], &
00262                 c__1, &c_b1, &work[1], &c__1);
00263 
00264 /*        Compute componentwise relative backward error from formula */
00265 
00266 /*        max(i) ( abs(R(i)) / ( abs(A)*abs(X) + abs(B) )(i) ) */
00267 
00268 /*        where abs(Z) is the componentwise absolute value of the matrix */
00269 /*        or vector Z.  If the i-th component of the denominator is less */
00270 /*        than SAFE2, then SAFE1 is added to the i-th components of the */
00271 /*        numerator and denominator before dividing. */
00272 
00273         i__2 = *n;
00274         for (i__ = 1; i__ <= i__2; ++i__) {
00275             i__3 = i__ + j * b_dim1;
00276             rwork[i__] = (r__1 = b[i__3].r, dabs(r__1)) + (r__2 = r_imag(&b[
00277                     i__ + j * b_dim1]), dabs(r__2));
00278 /* L30: */
00279         }
00280 
00281 /*        Compute abs(A)*abs(X) + abs(B). */
00282 
00283         if (upper) {
00284             i__2 = *n;
00285             for (k = 1; k <= i__2; ++k) {
00286                 s = 0.f;
00287                 i__3 = k + j * x_dim1;
00288                 xk = (r__1 = x[i__3].r, dabs(r__1)) + (r__2 = r_imag(&x[k + j 
00289                         * x_dim1]), dabs(r__2));
00290                 l = *kd + 1 - k;
00291 /* Computing MAX */
00292                 i__3 = 1, i__4 = k - *kd;
00293                 i__5 = k - 1;
00294                 for (i__ = max(i__3,i__4); i__ <= i__5; ++i__) {
00295                     i__3 = l + i__ + k * ab_dim1;
00296                     rwork[i__] += ((r__1 = ab[i__3].r, dabs(r__1)) + (r__2 = 
00297                             r_imag(&ab[l + i__ + k * ab_dim1]), dabs(r__2))) *
00298                              xk;
00299                     i__3 = l + i__ + k * ab_dim1;
00300                     i__4 = i__ + j * x_dim1;
00301                     s += ((r__1 = ab[i__3].r, dabs(r__1)) + (r__2 = r_imag(&
00302                             ab[l + i__ + k * ab_dim1]), dabs(r__2))) * ((r__3 
00303                             = x[i__4].r, dabs(r__3)) + (r__4 = r_imag(&x[i__ 
00304                             + j * x_dim1]), dabs(r__4)));
00305 /* L40: */
00306                 }
00307                 i__5 = *kd + 1 + k * ab_dim1;
00308                 rwork[k] = rwork[k] + (r__1 = ab[i__5].r, dabs(r__1)) * xk + 
00309                         s;
00310 /* L50: */
00311             }
00312         } else {
00313             i__2 = *n;
00314             for (k = 1; k <= i__2; ++k) {
00315                 s = 0.f;
00316                 i__5 = k + j * x_dim1;
00317                 xk = (r__1 = x[i__5].r, dabs(r__1)) + (r__2 = r_imag(&x[k + j 
00318                         * x_dim1]), dabs(r__2));
00319                 i__5 = k * ab_dim1 + 1;
00320                 rwork[k] += (r__1 = ab[i__5].r, dabs(r__1)) * xk;
00321                 l = 1 - k;
00322 /* Computing MIN */
00323                 i__3 = *n, i__4 = k + *kd;
00324                 i__5 = min(i__3,i__4);
00325                 for (i__ = k + 1; i__ <= i__5; ++i__) {
00326                     i__3 = l + i__ + k * ab_dim1;
00327                     rwork[i__] += ((r__1 = ab[i__3].r, dabs(r__1)) + (r__2 = 
00328                             r_imag(&ab[l + i__ + k * ab_dim1]), dabs(r__2))) *
00329                              xk;
00330                     i__3 = l + i__ + k * ab_dim1;
00331                     i__4 = i__ + j * x_dim1;
00332                     s += ((r__1 = ab[i__3].r, dabs(r__1)) + (r__2 = r_imag(&
00333                             ab[l + i__ + k * ab_dim1]), dabs(r__2))) * ((r__3 
00334                             = x[i__4].r, dabs(r__3)) + (r__4 = r_imag(&x[i__ 
00335                             + j * x_dim1]), dabs(r__4)));
00336 /* L60: */
00337                 }
00338                 rwork[k] += s;
00339 /* L70: */
00340             }
00341         }
00342         s = 0.f;
00343         i__2 = *n;
00344         for (i__ = 1; i__ <= i__2; ++i__) {
00345             if (rwork[i__] > safe2) {
00346 /* Computing MAX */
00347                 i__5 = i__;
00348                 r__3 = s, r__4 = ((r__1 = work[i__5].r, dabs(r__1)) + (r__2 = 
00349                         r_imag(&work[i__]), dabs(r__2))) / rwork[i__];
00350                 s = dmax(r__3,r__4);
00351             } else {
00352 /* Computing MAX */
00353                 i__5 = i__;
00354                 r__3 = s, r__4 = ((r__1 = work[i__5].r, dabs(r__1)) + (r__2 = 
00355                         r_imag(&work[i__]), dabs(r__2)) + safe1) / (rwork[i__]
00356                          + safe1);
00357                 s = dmax(r__3,r__4);
00358             }
00359 /* L80: */
00360         }
00361         berr[j] = s;
00362 
00363 /*        Test stopping criterion. Continue iterating if */
00364 /*           1) The residual BERR(J) is larger than machine epsilon, and */
00365 /*           2) BERR(J) decreased by at least a factor of 2 during the */
00366 /*              last iteration, and */
00367 /*           3) At most ITMAX iterations tried. */
00368 
00369         if (berr[j] > eps && berr[j] * 2.f <= lstres && count <= 5) {
00370 
00371 /*           Update solution and try again. */
00372 
00373             cpbtrs_(uplo, n, kd, &c__1, &afb[afb_offset], ldafb, &work[1], n, 
00374                     info);
00375             caxpy_(n, &c_b1, &work[1], &c__1, &x[j * x_dim1 + 1], &c__1);
00376             lstres = berr[j];
00377             ++count;
00378             goto L20;
00379         }
00380 
00381 /*        Bound error from formula */
00382 
00383 /*        norm(X - XTRUE) / norm(X) .le. FERR = */
00384 /*        norm( abs(inv(A))* */
00385 /*           ( abs(R) + NZ*EPS*( abs(A)*abs(X)+abs(B) ))) / norm(X) */
00386 
00387 /*        where */
00388 /*          norm(Z) is the magnitude of the largest component of Z */
00389 /*          inv(A) is the inverse of A */
00390 /*          abs(Z) is the componentwise absolute value of the matrix or */
00391 /*             vector Z */
00392 /*          NZ is the maximum number of nonzeros in any row of A, plus 1 */
00393 /*          EPS is machine epsilon */
00394 
00395 /*        The i-th component of abs(R)+NZ*EPS*(abs(A)*abs(X)+abs(B)) */
00396 /*        is incremented by SAFE1 if the i-th component of */
00397 /*        abs(A)*abs(X) + abs(B) is less than SAFE2. */
00398 
00399 /*        Use CLACN2 to estimate the infinity-norm of the matrix */
00400 /*           inv(A) * diag(W), */
00401 /*        where W = abs(R) + NZ*EPS*( abs(A)*abs(X)+abs(B) ))) */
00402 
00403         i__2 = *n;
00404         for (i__ = 1; i__ <= i__2; ++i__) {
00405             if (rwork[i__] > safe2) {
00406                 i__5 = i__;
00407                 rwork[i__] = (r__1 = work[i__5].r, dabs(r__1)) + (r__2 = 
00408                         r_imag(&work[i__]), dabs(r__2)) + nz * eps * rwork[
00409                         i__];
00410             } else {
00411                 i__5 = i__;
00412                 rwork[i__] = (r__1 = work[i__5].r, dabs(r__1)) + (r__2 = 
00413                         r_imag(&work[i__]), dabs(r__2)) + nz * eps * rwork[
00414                         i__] + safe1;
00415             }
00416 /* L90: */
00417         }
00418 
00419         kase = 0;
00420 L100:
00421         clacn2_(n, &work[*n + 1], &work[1], &ferr[j], &kase, isave);
00422         if (kase != 0) {
00423             if (kase == 1) {
00424 
00425 /*              Multiply by diag(W)*inv(A'). */
00426 
00427                 cpbtrs_(uplo, n, kd, &c__1, &afb[afb_offset], ldafb, &work[1], 
00428                          n, info);
00429                 i__2 = *n;
00430                 for (i__ = 1; i__ <= i__2; ++i__) {
00431                     i__5 = i__;
00432                     i__3 = i__;
00433                     i__4 = i__;
00434                     q__1.r = rwork[i__3] * work[i__4].r, q__1.i = rwork[i__3] 
00435                             * work[i__4].i;
00436                     work[i__5].r = q__1.r, work[i__5].i = q__1.i;
00437 /* L110: */
00438                 }
00439             } else if (kase == 2) {
00440 
00441 /*              Multiply by inv(A)*diag(W). */
00442 
00443                 i__2 = *n;
00444                 for (i__ = 1; i__ <= i__2; ++i__) {
00445                     i__5 = i__;
00446                     i__3 = i__;
00447                     i__4 = i__;
00448                     q__1.r = rwork[i__3] * work[i__4].r, q__1.i = rwork[i__3] 
00449                             * work[i__4].i;
00450                     work[i__5].r = q__1.r, work[i__5].i = q__1.i;
00451 /* L120: */
00452                 }
00453                 cpbtrs_(uplo, n, kd, &c__1, &afb[afb_offset], ldafb, &work[1], 
00454                          n, info);
00455             }
00456             goto L100;
00457         }
00458 
00459 /*        Normalize error. */
00460 
00461         lstres = 0.f;
00462         i__2 = *n;
00463         for (i__ = 1; i__ <= i__2; ++i__) {
00464 /* Computing MAX */
00465             i__5 = i__ + j * x_dim1;
00466             r__3 = lstres, r__4 = (r__1 = x[i__5].r, dabs(r__1)) + (r__2 = 
00467                     r_imag(&x[i__ + j * x_dim1]), dabs(r__2));
00468             lstres = dmax(r__3,r__4);
00469 /* L130: */
00470         }
00471         if (lstres != 0.f) {
00472             ferr[j] /= lstres;
00473         }
00474 
00475 /* L140: */
00476     }
00477 
00478     return 0;
00479 
00480 /*     End of CPBRFS */
00481 
00482 } /* cpbrfs_ */


swiftnav
Author(s):
autogenerated on Sat Jun 8 2019 18:55:32