dsytrs.c
Go to the documentation of this file.
00001 /* dsytrs.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 doublereal c_b7 = -1.;
00019 static integer c__1 = 1;
00020 static doublereal c_b19 = 1.;
00021 
00022 /* Subroutine */ int dsytrs_(char *uplo, integer *n, integer *nrhs, 
00023         doublereal *a, integer *lda, integer *ipiv, doublereal *b, integer *
00024         ldb, integer *info)
00025 {
00026     /* System generated locals */
00027     integer a_dim1, a_offset, b_dim1, b_offset, i__1;
00028     doublereal d__1;
00029 
00030     /* Local variables */
00031     integer j, k;
00032     doublereal ak, bk;
00033     integer kp;
00034     doublereal akm1, bkm1;
00035     extern /* Subroutine */ int dger_(integer *, integer *, doublereal *, 
00036             doublereal *, integer *, doublereal *, integer *, doublereal *, 
00037             integer *);
00038     doublereal akm1k;
00039     extern /* Subroutine */ int dscal_(integer *, doublereal *, doublereal *, 
00040             integer *);
00041     extern logical lsame_(char *, char *);
00042     doublereal denom;
00043     extern /* Subroutine */ int dgemv_(char *, integer *, integer *, 
00044             doublereal *, doublereal *, integer *, doublereal *, integer *, 
00045             doublereal *, doublereal *, integer *), dswap_(integer *, 
00046             doublereal *, integer *, doublereal *, integer *);
00047     logical upper;
00048     extern /* Subroutine */ int xerbla_(char *, integer *);
00049 
00050 
00051 /*  -- LAPACK routine (version 3.2) -- */
00052 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00053 /*     November 2006 */
00054 
00055 /*     .. Scalar Arguments .. */
00056 /*     .. */
00057 /*     .. Array Arguments .. */
00058 /*     .. */
00059 
00060 /*  Purpose */
00061 /*  ======= */
00062 
00063 /*  DSYTRS solves a system of linear equations A*X = B with a real */
00064 /*  symmetric matrix A using the factorization A = U*D*U**T or */
00065 /*  A = L*D*L**T computed by DSYTRF. */
00066 
00067 /*  Arguments */
00068 /*  ========= */
00069 
00070 /*  UPLO    (input) CHARACTER*1 */
00071 /*          Specifies whether the details of the factorization are stored */
00072 /*          as an upper or lower triangular matrix. */
00073 /*          = 'U':  Upper triangular, form is A = U*D*U**T; */
00074 /*          = 'L':  Lower triangular, form is A = L*D*L**T. */
00075 
00076 /*  N       (input) INTEGER */
00077 /*          The order of the matrix A.  N >= 0. */
00078 
00079 /*  NRHS    (input) INTEGER */
00080 /*          The number of right hand sides, i.e., the number of columns */
00081 /*          of the matrix B.  NRHS >= 0. */
00082 
00083 /*  A       (input) DOUBLE PRECISION array, dimension (LDA,N) */
00084 /*          The block diagonal matrix D and the multipliers used to */
00085 /*          obtain the factor U or L as computed by DSYTRF. */
00086 
00087 /*  LDA     (input) INTEGER */
00088 /*          The leading dimension of the array A.  LDA >= max(1,N). */
00089 
00090 /*  IPIV    (input) INTEGER array, dimension (N) */
00091 /*          Details of the interchanges and the block structure of D */
00092 /*          as determined by DSYTRF. */
00093 
00094 /*  B       (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS) */
00095 /*          On entry, the right hand side matrix B. */
00096 /*          On exit, the solution matrix X. */
00097 
00098 /*  LDB     (input) INTEGER */
00099 /*          The leading dimension of the array B.  LDB >= max(1,N). */
00100 
00101 /*  INFO    (output) INTEGER */
00102 /*          = 0:  successful exit */
00103 /*          < 0:  if INFO = -i, the i-th argument had an illegal value */
00104 
00105 /*  ===================================================================== */
00106 
00107 /*     .. Parameters .. */
00108 /*     .. */
00109 /*     .. Local Scalars .. */
00110 /*     .. */
00111 /*     .. External Functions .. */
00112 /*     .. */
00113 /*     .. External Subroutines .. */
00114 /*     .. */
00115 /*     .. Intrinsic Functions .. */
00116 /*     .. */
00117 /*     .. Executable Statements .. */
00118 
00119     /* Parameter adjustments */
00120     a_dim1 = *lda;
00121     a_offset = 1 + a_dim1;
00122     a -= a_offset;
00123     --ipiv;
00124     b_dim1 = *ldb;
00125     b_offset = 1 + b_dim1;
00126     b -= b_offset;
00127 
00128     /* Function Body */
00129     *info = 0;
00130     upper = lsame_(uplo, "U");
00131     if (! upper && ! lsame_(uplo, "L")) {
00132         *info = -1;
00133     } else if (*n < 0) {
00134         *info = -2;
00135     } else if (*nrhs < 0) {
00136         *info = -3;
00137     } else if (*lda < max(1,*n)) {
00138         *info = -5;
00139     } else if (*ldb < max(1,*n)) {
00140         *info = -8;
00141     }
00142     if (*info != 0) {
00143         i__1 = -(*info);
00144         xerbla_("DSYTRS", &i__1);
00145         return 0;
00146     }
00147 
00148 /*     Quick return if possible */
00149 
00150     if (*n == 0 || *nrhs == 0) {
00151         return 0;
00152     }
00153 
00154     if (upper) {
00155 
00156 /*        Solve A*X = B, where A = U*D*U'. */
00157 
00158 /*        First solve U*D*X = B, overwriting B with X. */
00159 
00160 /*        K is the main loop index, decreasing from N to 1 in steps of */
00161 /*        1 or 2, depending on the size of the diagonal blocks. */
00162 
00163         k = *n;
00164 L10:
00165 
00166 /*        If K < 1, exit from loop. */
00167 
00168         if (k < 1) {
00169             goto L30;
00170         }
00171 
00172         if (ipiv[k] > 0) {
00173 
00174 /*           1 x 1 diagonal block */
00175 
00176 /*           Interchange rows K and IPIV(K). */
00177 
00178             kp = ipiv[k];
00179             if (kp != k) {
00180                 dswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], ldb);
00181             }
00182 
00183 /*           Multiply by inv(U(K)), where U(K) is the transformation */
00184 /*           stored in column K of A. */
00185 
00186             i__1 = k - 1;
00187             dger_(&i__1, nrhs, &c_b7, &a[k * a_dim1 + 1], &c__1, &b[k + 
00188                     b_dim1], ldb, &b[b_dim1 + 1], ldb);
00189 
00190 /*           Multiply by the inverse of the diagonal block. */
00191 
00192             d__1 = 1. / a[k + k * a_dim1];
00193             dscal_(nrhs, &d__1, &b[k + b_dim1], ldb);
00194             --k;
00195         } else {
00196 
00197 /*           2 x 2 diagonal block */
00198 
00199 /*           Interchange rows K-1 and -IPIV(K). */
00200 
00201             kp = -ipiv[k];
00202             if (kp != k - 1) {
00203                 dswap_(nrhs, &b[k - 1 + b_dim1], ldb, &b[kp + b_dim1], ldb);
00204             }
00205 
00206 /*           Multiply by inv(U(K)), where U(K) is the transformation */
00207 /*           stored in columns K-1 and K of A. */
00208 
00209             i__1 = k - 2;
00210             dger_(&i__1, nrhs, &c_b7, &a[k * a_dim1 + 1], &c__1, &b[k + 
00211                     b_dim1], ldb, &b[b_dim1 + 1], ldb);
00212             i__1 = k - 2;
00213             dger_(&i__1, nrhs, &c_b7, &a[(k - 1) * a_dim1 + 1], &c__1, &b[k - 
00214                     1 + b_dim1], ldb, &b[b_dim1 + 1], ldb);
00215 
00216 /*           Multiply by the inverse of the diagonal block. */
00217 
00218             akm1k = a[k - 1 + k * a_dim1];
00219             akm1 = a[k - 1 + (k - 1) * a_dim1] / akm1k;
00220             ak = a[k + k * a_dim1] / akm1k;
00221             denom = akm1 * ak - 1.;
00222             i__1 = *nrhs;
00223             for (j = 1; j <= i__1; ++j) {
00224                 bkm1 = b[k - 1 + j * b_dim1] / akm1k;
00225                 bk = b[k + j * b_dim1] / akm1k;
00226                 b[k - 1 + j * b_dim1] = (ak * bkm1 - bk) / denom;
00227                 b[k + j * b_dim1] = (akm1 * bk - bkm1) / denom;
00228 /* L20: */
00229             }
00230             k += -2;
00231         }
00232 
00233         goto L10;
00234 L30:
00235 
00236 /*        Next solve U'*X = B, overwriting B with X. */
00237 
00238 /*        K is the main loop index, increasing from 1 to N in steps of */
00239 /*        1 or 2, depending on the size of the diagonal blocks. */
00240 
00241         k = 1;
00242 L40:
00243 
00244 /*        If K > N, exit from loop. */
00245 
00246         if (k > *n) {
00247             goto L50;
00248         }
00249 
00250         if (ipiv[k] > 0) {
00251 
00252 /*           1 x 1 diagonal block */
00253 
00254 /*           Multiply by inv(U'(K)), where U(K) is the transformation */
00255 /*           stored in column K of A. */
00256 
00257             i__1 = k - 1;
00258             dgemv_("Transpose", &i__1, nrhs, &c_b7, &b[b_offset], ldb, &a[k * 
00259                     a_dim1 + 1], &c__1, &c_b19, &b[k + b_dim1], ldb);
00260 
00261 /*           Interchange rows K and IPIV(K). */
00262 
00263             kp = ipiv[k];
00264             if (kp != k) {
00265                 dswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], ldb);
00266             }
00267             ++k;
00268         } else {
00269 
00270 /*           2 x 2 diagonal block */
00271 
00272 /*           Multiply by inv(U'(K+1)), where U(K+1) is the transformation */
00273 /*           stored in columns K and K+1 of A. */
00274 
00275             i__1 = k - 1;
00276             dgemv_("Transpose", &i__1, nrhs, &c_b7, &b[b_offset], ldb, &a[k * 
00277                     a_dim1 + 1], &c__1, &c_b19, &b[k + b_dim1], ldb);
00278             i__1 = k - 1;
00279             dgemv_("Transpose", &i__1, nrhs, &c_b7, &b[b_offset], ldb, &a[(k 
00280                     + 1) * a_dim1 + 1], &c__1, &c_b19, &b[k + 1 + b_dim1], 
00281                     ldb);
00282 
00283 /*           Interchange rows K and -IPIV(K). */
00284 
00285             kp = -ipiv[k];
00286             if (kp != k) {
00287                 dswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], ldb);
00288             }
00289             k += 2;
00290         }
00291 
00292         goto L40;
00293 L50:
00294 
00295         ;
00296     } else {
00297 
00298 /*        Solve A*X = B, where A = L*D*L'. */
00299 
00300 /*        First solve L*D*X = B, overwriting B with X. */
00301 
00302 /*        K is the main loop index, increasing from 1 to N in steps of */
00303 /*        1 or 2, depending on the size of the diagonal blocks. */
00304 
00305         k = 1;
00306 L60:
00307 
00308 /*        If K > N, exit from loop. */
00309 
00310         if (k > *n) {
00311             goto L80;
00312         }
00313 
00314         if (ipiv[k] > 0) {
00315 
00316 /*           1 x 1 diagonal block */
00317 
00318 /*           Interchange rows K and IPIV(K). */
00319 
00320             kp = ipiv[k];
00321             if (kp != k) {
00322                 dswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], ldb);
00323             }
00324 
00325 /*           Multiply by inv(L(K)), where L(K) is the transformation */
00326 /*           stored in column K of A. */
00327 
00328             if (k < *n) {
00329                 i__1 = *n - k;
00330                 dger_(&i__1, nrhs, &c_b7, &a[k + 1 + k * a_dim1], &c__1, &b[k 
00331                         + b_dim1], ldb, &b[k + 1 + b_dim1], ldb);
00332             }
00333 
00334 /*           Multiply by the inverse of the diagonal block. */
00335 
00336             d__1 = 1. / a[k + k * a_dim1];
00337             dscal_(nrhs, &d__1, &b[k + b_dim1], ldb);
00338             ++k;
00339         } else {
00340 
00341 /*           2 x 2 diagonal block */
00342 
00343 /*           Interchange rows K+1 and -IPIV(K). */
00344 
00345             kp = -ipiv[k];
00346             if (kp != k + 1) {
00347                 dswap_(nrhs, &b[k + 1 + b_dim1], ldb, &b[kp + b_dim1], ldb);
00348             }
00349 
00350 /*           Multiply by inv(L(K)), where L(K) is the transformation */
00351 /*           stored in columns K and K+1 of A. */
00352 
00353             if (k < *n - 1) {
00354                 i__1 = *n - k - 1;
00355                 dger_(&i__1, nrhs, &c_b7, &a[k + 2 + k * a_dim1], &c__1, &b[k 
00356                         + b_dim1], ldb, &b[k + 2 + b_dim1], ldb);
00357                 i__1 = *n - k - 1;
00358                 dger_(&i__1, nrhs, &c_b7, &a[k + 2 + (k + 1) * a_dim1], &c__1, 
00359                          &b[k + 1 + b_dim1], ldb, &b[k + 2 + b_dim1], ldb);
00360             }
00361 
00362 /*           Multiply by the inverse of the diagonal block. */
00363 
00364             akm1k = a[k + 1 + k * a_dim1];
00365             akm1 = a[k + k * a_dim1] / akm1k;
00366             ak = a[k + 1 + (k + 1) * a_dim1] / akm1k;
00367             denom = akm1 * ak - 1.;
00368             i__1 = *nrhs;
00369             for (j = 1; j <= i__1; ++j) {
00370                 bkm1 = b[k + j * b_dim1] / akm1k;
00371                 bk = b[k + 1 + j * b_dim1] / akm1k;
00372                 b[k + j * b_dim1] = (ak * bkm1 - bk) / denom;
00373                 b[k + 1 + j * b_dim1] = (akm1 * bk - bkm1) / denom;
00374 /* L70: */
00375             }
00376             k += 2;
00377         }
00378 
00379         goto L60;
00380 L80:
00381 
00382 /*        Next solve L'*X = B, overwriting B with X. */
00383 
00384 /*        K is the main loop index, decreasing from N to 1 in steps of */
00385 /*        1 or 2, depending on the size of the diagonal blocks. */
00386 
00387         k = *n;
00388 L90:
00389 
00390 /*        If K < 1, exit from loop. */
00391 
00392         if (k < 1) {
00393             goto L100;
00394         }
00395 
00396         if (ipiv[k] > 0) {
00397 
00398 /*           1 x 1 diagonal block */
00399 
00400 /*           Multiply by inv(L'(K)), where L(K) is the transformation */
00401 /*           stored in column K of A. */
00402 
00403             if (k < *n) {
00404                 i__1 = *n - k;
00405                 dgemv_("Transpose", &i__1, nrhs, &c_b7, &b[k + 1 + b_dim1], 
00406                         ldb, &a[k + 1 + k * a_dim1], &c__1, &c_b19, &b[k + 
00407                         b_dim1], ldb);
00408             }
00409 
00410 /*           Interchange rows K and IPIV(K). */
00411 
00412             kp = ipiv[k];
00413             if (kp != k) {
00414                 dswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], ldb);
00415             }
00416             --k;
00417         } else {
00418 
00419 /*           2 x 2 diagonal block */
00420 
00421 /*           Multiply by inv(L'(K-1)), where L(K-1) is the transformation */
00422 /*           stored in columns K-1 and K of A. */
00423 
00424             if (k < *n) {
00425                 i__1 = *n - k;
00426                 dgemv_("Transpose", &i__1, nrhs, &c_b7, &b[k + 1 + b_dim1], 
00427                         ldb, &a[k + 1 + k * a_dim1], &c__1, &c_b19, &b[k + 
00428                         b_dim1], ldb);
00429                 i__1 = *n - k;
00430                 dgemv_("Transpose", &i__1, nrhs, &c_b7, &b[k + 1 + b_dim1], 
00431                         ldb, &a[k + 1 + (k - 1) * a_dim1], &c__1, &c_b19, &b[
00432                         k - 1 + b_dim1], ldb);
00433             }
00434 
00435 /*           Interchange rows K and -IPIV(K). */
00436 
00437             kp = -ipiv[k];
00438             if (kp != k) {
00439                 dswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], ldb);
00440             }
00441             k += -2;
00442         }
00443 
00444         goto L90;
00445 L100:
00446         ;
00447     }
00448 
00449     return 0;
00450 
00451 /*     End of DSYTRS */
00452 
00453 } /* dsytrs_ */


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