ztrrfs.c
Go to the documentation of this file.
00001 /* ztrrfs.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 
00020 /* Subroutine */ int ztrrfs_(char *uplo, char *trans, char *diag, integer *n, 
00021         integer *nrhs, doublecomplex *a, integer *lda, doublecomplex *b, 
00022         integer *ldb, doublecomplex *x, integer *ldx, doublereal *ferr, 
00023         doublereal *berr, doublecomplex *work, doublereal *rwork, integer *
00024         info)
00025 {
00026     /* System generated locals */
00027     integer a_dim1, a_offset, b_dim1, b_offset, x_dim1, x_offset, i__1, i__2, 
00028             i__3, i__4, i__5;
00029     doublereal d__1, d__2, d__3, d__4;
00030     doublecomplex z__1;
00031 
00032     /* Builtin functions */
00033     double d_imag(doublecomplex *);
00034 
00035     /* Local variables */
00036     integer i__, j, k;
00037     doublereal s, xk;
00038     integer nz;
00039     doublereal eps;
00040     integer kase;
00041     doublereal safe1, safe2;
00042     extern logical lsame_(char *, char *);
00043     integer isave[3];
00044     logical upper;
00045     extern /* Subroutine */ int zcopy_(integer *, doublecomplex *, integer *, 
00046             doublecomplex *, integer *), zaxpy_(integer *, doublecomplex *, 
00047             doublecomplex *, integer *, doublecomplex *, integer *), ztrmv_(
00048             char *, char *, char *, integer *, doublecomplex *, integer *, 
00049             doublecomplex *, integer *), ztrsv_(char *
00050 , char *, char *, integer *, doublecomplex *, integer *, 
00051             doublecomplex *, integer *), zlacn2_(
00052             integer *, doublecomplex *, doublecomplex *, doublereal *, 
00053             integer *, integer *);
00054     extern doublereal dlamch_(char *);
00055     doublereal safmin;
00056     extern /* Subroutine */ int xerbla_(char *, integer *);
00057     logical notran;
00058     char transn[1], transt[1];
00059     logical nounit;
00060     doublereal lstres;
00061 
00062 
00063 /*  -- LAPACK routine (version 3.2) -- */
00064 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00065 /*     November 2006 */
00066 
00067 /*     Modified to call ZLACN2 in place of ZLACON, 10 Feb 03, SJH. */
00068 
00069 /*     .. Scalar Arguments .. */
00070 /*     .. */
00071 /*     .. Array Arguments .. */
00072 /*     .. */
00073 
00074 /*  Purpose */
00075 /*  ======= */
00076 
00077 /*  ZTRRFS provides error bounds and backward error estimates for the */
00078 /*  solution to a system of linear equations with a triangular */
00079 /*  coefficient matrix. */
00080 
00081 /*  The solution matrix X must be computed by ZTRTRS or some other */
00082 /*  means before entering this routine.  ZTRRFS does not do iterative */
00083 /*  refinement because doing so cannot improve the backward error. */
00084 
00085 /*  Arguments */
00086 /*  ========= */
00087 
00088 /*  UPLO    (input) CHARACTER*1 */
00089 /*          = 'U':  A is upper triangular; */
00090 /*          = 'L':  A is lower triangular. */
00091 
00092 /*  TRANS   (input) CHARACTER*1 */
00093 /*          Specifies the form of the system of equations: */
00094 /*          = 'N':  A * X = B     (No transpose) */
00095 /*          = 'T':  A**T * X = B  (Transpose) */
00096 /*          = 'C':  A**H * X = B  (Conjugate transpose) */
00097 
00098 /*  DIAG    (input) CHARACTER*1 */
00099 /*          = 'N':  A is non-unit triangular; */
00100 /*          = 'U':  A is unit triangular. */
00101 
00102 /*  N       (input) INTEGER */
00103 /*          The order of the matrix A.  N >= 0. */
00104 
00105 /*  NRHS    (input) INTEGER */
00106 /*          The number of right hand sides, i.e., the number of columns */
00107 /*          of the matrices B and X.  NRHS >= 0. */
00108 
00109 /*  A       (input) COMPLEX*16 array, dimension (LDA,N) */
00110 /*          The triangular matrix A.  If UPLO = 'U', the leading N-by-N */
00111 /*          upper triangular part of the array A contains the upper */
00112 /*          triangular matrix, and the strictly lower triangular part of */
00113 /*          A is not referenced.  If UPLO = 'L', the leading N-by-N lower */
00114 /*          triangular part of the array A contains the lower triangular */
00115 /*          matrix, and the strictly upper triangular part of A is not */
00116 /*          referenced.  If DIAG = 'U', the diagonal elements of A are */
00117 /*          also not referenced and are assumed to be 1. */
00118 
00119 /*  LDA     (input) INTEGER */
00120 /*          The leading dimension of the array A.  LDA >= max(1,N). */
00121 
00122 /*  B       (input) COMPLEX*16 array, dimension (LDB,NRHS) */
00123 /*          The right hand side matrix B. */
00124 
00125 /*  LDB     (input) INTEGER */
00126 /*          The leading dimension of the array B.  LDB >= max(1,N). */
00127 
00128 /*  X       (input) COMPLEX*16 array, dimension (LDX,NRHS) */
00129 /*          The solution matrix X. */
00130 
00131 /*  LDX     (input) INTEGER */
00132 /*          The leading dimension of the array X.  LDX >= max(1,N). */
00133 
00134 /*  FERR    (output) DOUBLE PRECISION array, dimension (NRHS) */
00135 /*          The estimated forward error bound for each solution vector */
00136 /*          X(j) (the j-th column of the solution matrix X). */
00137 /*          If XTRUE is the true solution corresponding to X(j), FERR(j) */
00138 /*          is an estimated upper bound for the magnitude of the largest */
00139 /*          element in (X(j) - XTRUE) divided by the magnitude of the */
00140 /*          largest element in X(j).  The estimate is as reliable as */
00141 /*          the estimate for RCOND, and is almost always a slight */
00142 /*          overestimate of the true error. */
00143 
00144 /*  BERR    (output) DOUBLE PRECISION array, dimension (NRHS) */
00145 /*          The componentwise relative backward error of each solution */
00146 /*          vector X(j) (i.e., the smallest relative change in */
00147 /*          any element of A or B that makes X(j) an exact solution). */
00148 
00149 /*  WORK    (workspace) COMPLEX*16 array, dimension (2*N) */
00150 
00151 /*  RWORK   (workspace) DOUBLE PRECISION array, dimension (N) */
00152 
00153 /*  INFO    (output) INTEGER */
00154 /*          = 0:  successful exit */
00155 /*          < 0:  if INFO = -i, the i-th argument had an illegal value */
00156 
00157 /*  ===================================================================== */
00158 
00159 /*     .. Parameters .. */
00160 /*     .. */
00161 /*     .. Local Scalars .. */
00162 /*     .. */
00163 /*     .. Local Arrays .. */
00164 /*     .. */
00165 /*     .. External Subroutines .. */
00166 /*     .. */
00167 /*     .. Intrinsic Functions .. */
00168 /*     .. */
00169 /*     .. External Functions .. */
00170 /*     .. */
00171 /*     .. Statement Functions .. */
00172 /*     .. */
00173 /*     .. Statement Function definitions .. */
00174 /*     .. */
00175 /*     .. Executable Statements .. */
00176 
00177 /*     Test the input parameters. */
00178 
00179     /* Parameter adjustments */
00180     a_dim1 = *lda;
00181     a_offset = 1 + a_dim1;
00182     a -= a_offset;
00183     b_dim1 = *ldb;
00184     b_offset = 1 + b_dim1;
00185     b -= b_offset;
00186     x_dim1 = *ldx;
00187     x_offset = 1 + x_dim1;
00188     x -= x_offset;
00189     --ferr;
00190     --berr;
00191     --work;
00192     --rwork;
00193 
00194     /* Function Body */
00195     *info = 0;
00196     upper = lsame_(uplo, "U");
00197     notran = lsame_(trans, "N");
00198     nounit = lsame_(diag, "N");
00199 
00200     if (! upper && ! lsame_(uplo, "L")) {
00201         *info = -1;
00202     } else if (! notran && ! lsame_(trans, "T") && ! 
00203             lsame_(trans, "C")) {
00204         *info = -2;
00205     } else if (! nounit && ! lsame_(diag, "U")) {
00206         *info = -3;
00207     } else if (*n < 0) {
00208         *info = -4;
00209     } else if (*nrhs < 0) {
00210         *info = -5;
00211     } else if (*lda < max(1,*n)) {
00212         *info = -7;
00213     } else if (*ldb < max(1,*n)) {
00214         *info = -9;
00215     } else if (*ldx < max(1,*n)) {
00216         *info = -11;
00217     }
00218     if (*info != 0) {
00219         i__1 = -(*info);
00220         xerbla_("ZTRRFS", &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.;
00230             berr[j] = 0.;
00231 /* L10: */
00232         }
00233         return 0;
00234     }
00235 
00236     if (notran) {
00237         *(unsigned char *)transn = 'N';
00238         *(unsigned char *)transt = 'C';
00239     } else {
00240         *(unsigned char *)transn = 'C';
00241         *(unsigned char *)transt = 'N';
00242     }
00243 
00244 /*     NZ = maximum number of nonzero elements in each row of A, plus 1 */
00245 
00246     nz = *n + 1;
00247     eps = dlamch_("Epsilon");
00248     safmin = dlamch_("Safe minimum");
00249     safe1 = nz * safmin;
00250     safe2 = safe1 / eps;
00251 
00252 /*     Do for each right hand side */
00253 
00254     i__1 = *nrhs;
00255     for (j = 1; j <= i__1; ++j) {
00256 
00257 /*        Compute residual R = B - op(A) * X, */
00258 /*        where op(A) = A, A**T, or A**H, depending on TRANS. */
00259 
00260         zcopy_(n, &x[j * x_dim1 + 1], &c__1, &work[1], &c__1);
00261         ztrmv_(uplo, trans, diag, n, &a[a_offset], lda, &work[1], &c__1);
00262         z__1.r = -1., z__1.i = -0.;
00263         zaxpy_(n, &z__1, &b[j * b_dim1 + 1], &c__1, &work[1], &c__1);
00264 
00265 /*        Compute componentwise relative backward error from formula */
00266 
00267 /*        max(i) ( abs(R(i)) / ( abs(op(A))*abs(X) + abs(B) )(i) ) */
00268 
00269 /*        where abs(Z) is the componentwise absolute value of the matrix */
00270 /*        or vector Z.  If the i-th component of the denominator is less */
00271 /*        than SAFE2, then SAFE1 is added to the i-th components of the */
00272 /*        numerator and denominator before dividing. */
00273 
00274         i__2 = *n;
00275         for (i__ = 1; i__ <= i__2; ++i__) {
00276             i__3 = i__ + j * b_dim1;
00277             rwork[i__] = (d__1 = b[i__3].r, abs(d__1)) + (d__2 = d_imag(&b[
00278                     i__ + j * b_dim1]), abs(d__2));
00279 /* L20: */
00280         }
00281 
00282         if (notran) {
00283 
00284 /*           Compute abs(A)*abs(X) + abs(B). */
00285 
00286             if (upper) {
00287                 if (nounit) {
00288                     i__2 = *n;
00289                     for (k = 1; k <= i__2; ++k) {
00290                         i__3 = k + j * x_dim1;
00291                         xk = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(&
00292                                 x[k + j * x_dim1]), abs(d__2));
00293                         i__3 = k;
00294                         for (i__ = 1; i__ <= i__3; ++i__) {
00295                             i__4 = i__ + k * a_dim1;
00296                             rwork[i__] += ((d__1 = a[i__4].r, abs(d__1)) + (
00297                                     d__2 = d_imag(&a[i__ + k * a_dim1]), abs(
00298                                     d__2))) * xk;
00299 /* L30: */
00300                         }
00301 /* L40: */
00302                     }
00303                 } else {
00304                     i__2 = *n;
00305                     for (k = 1; k <= i__2; ++k) {
00306                         i__3 = k + j * x_dim1;
00307                         xk = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(&
00308                                 x[k + j * x_dim1]), abs(d__2));
00309                         i__3 = k - 1;
00310                         for (i__ = 1; i__ <= i__3; ++i__) {
00311                             i__4 = i__ + k * a_dim1;
00312                             rwork[i__] += ((d__1 = a[i__4].r, abs(d__1)) + (
00313                                     d__2 = d_imag(&a[i__ + k * a_dim1]), abs(
00314                                     d__2))) * xk;
00315 /* L50: */
00316                         }
00317                         rwork[k] += xk;
00318 /* L60: */
00319                     }
00320                 }
00321             } else {
00322                 if (nounit) {
00323                     i__2 = *n;
00324                     for (k = 1; k <= i__2; ++k) {
00325                         i__3 = k + j * x_dim1;
00326                         xk = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(&
00327                                 x[k + j * x_dim1]), abs(d__2));
00328                         i__3 = *n;
00329                         for (i__ = k; i__ <= i__3; ++i__) {
00330                             i__4 = i__ + k * a_dim1;
00331                             rwork[i__] += ((d__1 = a[i__4].r, abs(d__1)) + (
00332                                     d__2 = d_imag(&a[i__ + k * a_dim1]), abs(
00333                                     d__2))) * xk;
00334 /* L70: */
00335                         }
00336 /* L80: */
00337                     }
00338                 } else {
00339                     i__2 = *n;
00340                     for (k = 1; k <= i__2; ++k) {
00341                         i__3 = k + j * x_dim1;
00342                         xk = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(&
00343                                 x[k + j * x_dim1]), abs(d__2));
00344                         i__3 = *n;
00345                         for (i__ = k + 1; i__ <= i__3; ++i__) {
00346                             i__4 = i__ + k * a_dim1;
00347                             rwork[i__] += ((d__1 = a[i__4].r, abs(d__1)) + (
00348                                     d__2 = d_imag(&a[i__ + k * a_dim1]), abs(
00349                                     d__2))) * xk;
00350 /* L90: */
00351                         }
00352                         rwork[k] += xk;
00353 /* L100: */
00354                     }
00355                 }
00356             }
00357         } else {
00358 
00359 /*           Compute abs(A**H)*abs(X) + abs(B). */
00360 
00361             if (upper) {
00362                 if (nounit) {
00363                     i__2 = *n;
00364                     for (k = 1; k <= i__2; ++k) {
00365                         s = 0.;
00366                         i__3 = k;
00367                         for (i__ = 1; i__ <= i__3; ++i__) {
00368                             i__4 = i__ + k * a_dim1;
00369                             i__5 = i__ + j * x_dim1;
00370                             s += ((d__1 = a[i__4].r, abs(d__1)) + (d__2 = 
00371                                     d_imag(&a[i__ + k * a_dim1]), abs(d__2))) 
00372                                     * ((d__3 = x[i__5].r, abs(d__3)) + (d__4 =
00373                                      d_imag(&x[i__ + j * x_dim1]), abs(d__4)))
00374                                     ;
00375 /* L110: */
00376                         }
00377                         rwork[k] += s;
00378 /* L120: */
00379                     }
00380                 } else {
00381                     i__2 = *n;
00382                     for (k = 1; k <= i__2; ++k) {
00383                         i__3 = k + j * x_dim1;
00384                         s = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(&x[
00385                                 k + j * x_dim1]), abs(d__2));
00386                         i__3 = k - 1;
00387                         for (i__ = 1; i__ <= i__3; ++i__) {
00388                             i__4 = i__ + k * a_dim1;
00389                             i__5 = i__ + j * x_dim1;
00390                             s += ((d__1 = a[i__4].r, abs(d__1)) + (d__2 = 
00391                                     d_imag(&a[i__ + k * a_dim1]), abs(d__2))) 
00392                                     * ((d__3 = x[i__5].r, abs(d__3)) + (d__4 =
00393                                      d_imag(&x[i__ + j * x_dim1]), abs(d__4)))
00394                                     ;
00395 /* L130: */
00396                         }
00397                         rwork[k] += s;
00398 /* L140: */
00399                     }
00400                 }
00401             } else {
00402                 if (nounit) {
00403                     i__2 = *n;
00404                     for (k = 1; k <= i__2; ++k) {
00405                         s = 0.;
00406                         i__3 = *n;
00407                         for (i__ = k; i__ <= i__3; ++i__) {
00408                             i__4 = i__ + k * a_dim1;
00409                             i__5 = i__ + j * x_dim1;
00410                             s += ((d__1 = a[i__4].r, abs(d__1)) + (d__2 = 
00411                                     d_imag(&a[i__ + k * a_dim1]), abs(d__2))) 
00412                                     * ((d__3 = x[i__5].r, abs(d__3)) + (d__4 =
00413                                      d_imag(&x[i__ + j * x_dim1]), abs(d__4)))
00414                                     ;
00415 /* L150: */
00416                         }
00417                         rwork[k] += s;
00418 /* L160: */
00419                     }
00420                 } else {
00421                     i__2 = *n;
00422                     for (k = 1; k <= i__2; ++k) {
00423                         i__3 = k + j * x_dim1;
00424                         s = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = d_imag(&x[
00425                                 k + j * x_dim1]), abs(d__2));
00426                         i__3 = *n;
00427                         for (i__ = k + 1; i__ <= i__3; ++i__) {
00428                             i__4 = i__ + k * a_dim1;
00429                             i__5 = i__ + j * x_dim1;
00430                             s += ((d__1 = a[i__4].r, abs(d__1)) + (d__2 = 
00431                                     d_imag(&a[i__ + k * a_dim1]), abs(d__2))) 
00432                                     * ((d__3 = x[i__5].r, abs(d__3)) + (d__4 =
00433                                      d_imag(&x[i__ + j * x_dim1]), abs(d__4)))
00434                                     ;
00435 /* L170: */
00436                         }
00437                         rwork[k] += s;
00438 /* L180: */
00439                     }
00440                 }
00441             }
00442         }
00443         s = 0.;
00444         i__2 = *n;
00445         for (i__ = 1; i__ <= i__2; ++i__) {
00446             if (rwork[i__] > safe2) {
00447 /* Computing MAX */
00448                 i__3 = i__;
00449                 d__3 = s, d__4 = ((d__1 = work[i__3].r, abs(d__1)) + (d__2 = 
00450                         d_imag(&work[i__]), abs(d__2))) / rwork[i__];
00451                 s = max(d__3,d__4);
00452             } else {
00453 /* Computing MAX */
00454                 i__3 = i__;
00455                 d__3 = s, d__4 = ((d__1 = work[i__3].r, abs(d__1)) + (d__2 = 
00456                         d_imag(&work[i__]), abs(d__2)) + safe1) / (rwork[i__] 
00457                         + safe1);
00458                 s = max(d__3,d__4);
00459             }
00460 /* L190: */
00461         }
00462         berr[j] = s;
00463 
00464 /*        Bound error from formula */
00465 
00466 /*        norm(X - XTRUE) / norm(X) .le. FERR = */
00467 /*        norm( abs(inv(op(A)))* */
00468 /*           ( abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) / norm(X) */
00469 
00470 /*        where */
00471 /*          norm(Z) is the magnitude of the largest component of Z */
00472 /*          inv(op(A)) is the inverse of op(A) */
00473 /*          abs(Z) is the componentwise absolute value of the matrix or */
00474 /*             vector Z */
00475 /*          NZ is the maximum number of nonzeros in any row of A, plus 1 */
00476 /*          EPS is machine epsilon */
00477 
00478 /*        The i-th component of abs(R)+NZ*EPS*(abs(op(A))*abs(X)+abs(B)) */
00479 /*        is incremented by SAFE1 if the i-th component of */
00480 /*        abs(op(A))*abs(X) + abs(B) is less than SAFE2. */
00481 
00482 /*        Use ZLACN2 to estimate the infinity-norm of the matrix */
00483 /*           inv(op(A)) * diag(W), */
00484 /*        where W = abs(R) + NZ*EPS*( abs(op(A))*abs(X)+abs(B) ))) */
00485 
00486         i__2 = *n;
00487         for (i__ = 1; i__ <= i__2; ++i__) {
00488             if (rwork[i__] > safe2) {
00489                 i__3 = i__;
00490                 rwork[i__] = (d__1 = work[i__3].r, abs(d__1)) + (d__2 = 
00491                         d_imag(&work[i__]), abs(d__2)) + nz * eps * rwork[i__]
00492                         ;
00493             } else {
00494                 i__3 = i__;
00495                 rwork[i__] = (d__1 = work[i__3].r, abs(d__1)) + (d__2 = 
00496                         d_imag(&work[i__]), abs(d__2)) + nz * eps * rwork[i__]
00497                          + safe1;
00498             }
00499 /* L200: */
00500         }
00501 
00502         kase = 0;
00503 L210:
00504         zlacn2_(n, &work[*n + 1], &work[1], &ferr[j], &kase, isave);
00505         if (kase != 0) {
00506             if (kase == 1) {
00507 
00508 /*              Multiply by diag(W)*inv(op(A)**H). */
00509 
00510                 ztrsv_(uplo, transt, diag, n, &a[a_offset], lda, &work[1], &
00511                         c__1);
00512                 i__2 = *n;
00513                 for (i__ = 1; i__ <= i__2; ++i__) {
00514                     i__3 = i__;
00515                     i__4 = i__;
00516                     i__5 = i__;
00517                     z__1.r = rwork[i__4] * work[i__5].r, z__1.i = rwork[i__4] 
00518                             * work[i__5].i;
00519                     work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00520 /* L220: */
00521                 }
00522             } else {
00523 
00524 /*              Multiply by inv(op(A))*diag(W). */
00525 
00526                 i__2 = *n;
00527                 for (i__ = 1; i__ <= i__2; ++i__) {
00528                     i__3 = i__;
00529                     i__4 = i__;
00530                     i__5 = i__;
00531                     z__1.r = rwork[i__4] * work[i__5].r, z__1.i = rwork[i__4] 
00532                             * work[i__5].i;
00533                     work[i__3].r = z__1.r, work[i__3].i = z__1.i;
00534 /* L230: */
00535                 }
00536                 ztrsv_(uplo, transn, diag, n, &a[a_offset], lda, &work[1], &
00537                         c__1);
00538             }
00539             goto L210;
00540         }
00541 
00542 /*        Normalize error. */
00543 
00544         lstres = 0.;
00545         i__2 = *n;
00546         for (i__ = 1; i__ <= i__2; ++i__) {
00547 /* Computing MAX */
00548             i__3 = i__ + j * x_dim1;
00549             d__3 = lstres, d__4 = (d__1 = x[i__3].r, abs(d__1)) + (d__2 = 
00550                     d_imag(&x[i__ + j * x_dim1]), abs(d__2));
00551             lstres = max(d__3,d__4);
00552 /* L240: */
00553         }
00554         if (lstres != 0.) {
00555             ferr[j] /= lstres;
00556         }
00557 
00558 /* L250: */
00559     }
00560 
00561     return 0;
00562 
00563 /*     End of ZTRRFS */
00564 
00565 } /* ztrrfs_ */


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