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


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