ssptrs.c
Go to the documentation of this file.
00001 /* ssptrs.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 ssptrs_(char *uplo, integer *n, integer *nrhs, real *ap, 
00023         integer *ipiv, real *b, integer *ldb, integer *info)
00024 {
00025     /* System generated locals */
00026     integer b_dim1, b_offset, i__1;
00027     real r__1;
00028 
00029     /* Local variables */
00030     integer j, k;
00031     real ak, bk;
00032     integer kc, 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 /*  SSPTRS solves a system of linear equations A*X = B with a real */
00060 /*  symmetric matrix A stored in packed format using the factorization */
00061 /*  A = U*D*U**T or A = L*D*L**T computed by SSPTRF. */
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 /*  AP      (input) REAL array, dimension (N*(N+1)/2) */
00080 /*          The block diagonal matrix D and the multipliers used to */
00081 /*          obtain the factor U or L as computed by SSPTRF, stored as a */
00082 /*          packed triangular matrix. */
00083 
00084 /*  IPIV    (input) INTEGER array, dimension (N) */
00085 /*          Details of the interchanges and the block structure of D */
00086 /*          as determined by SSPTRF. */
00087 
00088 /*  B       (input/output) REAL array, dimension (LDB,NRHS) */
00089 /*          On entry, the right hand side matrix B. */
00090 /*          On exit, the solution matrix X. */
00091 
00092 /*  LDB     (input) INTEGER */
00093 /*          The leading dimension of the array B.  LDB >= max(1,N). */
00094 
00095 /*  INFO    (output) INTEGER */
00096 /*          = 0:  successful exit */
00097 /*          < 0: if INFO = -i, the i-th argument had an illegal value */
00098 
00099 /*  ===================================================================== */
00100 
00101 /*     .. Parameters .. */
00102 /*     .. */
00103 /*     .. Local Scalars .. */
00104 /*     .. */
00105 /*     .. External Functions .. */
00106 /*     .. */
00107 /*     .. External Subroutines .. */
00108 /*     .. */
00109 /*     .. Intrinsic Functions .. */
00110 /*     .. */
00111 /*     .. Executable Statements .. */
00112 
00113     /* Parameter adjustments */
00114     --ap;
00115     --ipiv;
00116     b_dim1 = *ldb;
00117     b_offset = 1 + b_dim1;
00118     b -= b_offset;
00119 
00120     /* Function Body */
00121     *info = 0;
00122     upper = lsame_(uplo, "U");
00123     if (! upper && ! lsame_(uplo, "L")) {
00124         *info = -1;
00125     } else if (*n < 0) {
00126         *info = -2;
00127     } else if (*nrhs < 0) {
00128         *info = -3;
00129     } else if (*ldb < max(1,*n)) {
00130         *info = -7;
00131     }
00132     if (*info != 0) {
00133         i__1 = -(*info);
00134         xerbla_("SSPTRS", &i__1);
00135         return 0;
00136     }
00137 
00138 /*     Quick return if possible */
00139 
00140     if (*n == 0 || *nrhs == 0) {
00141         return 0;
00142     }
00143 
00144     if (upper) {
00145 
00146 /*        Solve A*X = B, where A = U*D*U'. */
00147 
00148 /*        First solve U*D*X = B, overwriting B with X. */
00149 
00150 /*        K is the main loop index, decreasing from N to 1 in steps of */
00151 /*        1 or 2, depending on the size of the diagonal blocks. */
00152 
00153         k = *n;
00154         kc = *n * (*n + 1) / 2 + 1;
00155 L10:
00156 
00157 /*        If K < 1, exit from loop. */
00158 
00159         if (k < 1) {
00160             goto L30;
00161         }
00162 
00163         kc -= k;
00164         if (ipiv[k] > 0) {
00165 
00166 /*           1 x 1 diagonal block */
00167 
00168 /*           Interchange rows K and IPIV(K). */
00169 
00170             kp = ipiv[k];
00171             if (kp != k) {
00172                 sswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], ldb);
00173             }
00174 
00175 /*           Multiply by inv(U(K)), where U(K) is the transformation */
00176 /*           stored in column K of A. */
00177 
00178             i__1 = k - 1;
00179             sger_(&i__1, nrhs, &c_b7, &ap[kc], &c__1, &b[k + b_dim1], ldb, &b[
00180                     b_dim1 + 1], ldb);
00181 
00182 /*           Multiply by the inverse of the diagonal block. */
00183 
00184             r__1 = 1.f / ap[kc + k - 1];
00185             sscal_(nrhs, &r__1, &b[k + b_dim1], ldb);
00186             --k;
00187         } else {
00188 
00189 /*           2 x 2 diagonal block */
00190 
00191 /*           Interchange rows K-1 and -IPIV(K). */
00192 
00193             kp = -ipiv[k];
00194             if (kp != k - 1) {
00195                 sswap_(nrhs, &b[k - 1 + b_dim1], ldb, &b[kp + b_dim1], ldb);
00196             }
00197 
00198 /*           Multiply by inv(U(K)), where U(K) is the transformation */
00199 /*           stored in columns K-1 and K of A. */
00200 
00201             i__1 = k - 2;
00202             sger_(&i__1, nrhs, &c_b7, &ap[kc], &c__1, &b[k + b_dim1], ldb, &b[
00203                     b_dim1 + 1], ldb);
00204             i__1 = k - 2;
00205             sger_(&i__1, nrhs, &c_b7, &ap[kc - (k - 1)], &c__1, &b[k - 1 + 
00206                     b_dim1], ldb, &b[b_dim1 + 1], ldb);
00207 
00208 /*           Multiply by the inverse of the diagonal block. */
00209 
00210             akm1k = ap[kc + k - 2];
00211             akm1 = ap[kc - 1] / akm1k;
00212             ak = ap[kc + k - 1] / akm1k;
00213             denom = akm1 * ak - 1.f;
00214             i__1 = *nrhs;
00215             for (j = 1; j <= i__1; ++j) {
00216                 bkm1 = b[k - 1 + j * b_dim1] / akm1k;
00217                 bk = b[k + j * b_dim1] / akm1k;
00218                 b[k - 1 + j * b_dim1] = (ak * bkm1 - bk) / denom;
00219                 b[k + j * b_dim1] = (akm1 * bk - bkm1) / denom;
00220 /* L20: */
00221             }
00222             kc = kc - k + 1;
00223             k += -2;
00224         }
00225 
00226         goto L10;
00227 L30:
00228 
00229 /*        Next solve U'*X = B, overwriting B with X. */
00230 
00231 /*        K is the main loop index, increasing from 1 to N in steps of */
00232 /*        1 or 2, depending on the size of the diagonal blocks. */
00233 
00234         k = 1;
00235         kc = 1;
00236 L40:
00237 
00238 /*        If K > N, exit from loop. */
00239 
00240         if (k > *n) {
00241             goto L50;
00242         }
00243 
00244         if (ipiv[k] > 0) {
00245 
00246 /*           1 x 1 diagonal block */
00247 
00248 /*           Multiply by inv(U'(K)), where U(K) is the transformation */
00249 /*           stored in column K of A. */
00250 
00251             i__1 = k - 1;
00252             sgemv_("Transpose", &i__1, nrhs, &c_b7, &b[b_offset], ldb, &ap[kc]
00253 , &c__1, &c_b19, &b[k + b_dim1], ldb);
00254 
00255 /*           Interchange rows K and IPIV(K). */
00256 
00257             kp = ipiv[k];
00258             if (kp != k) {
00259                 sswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], ldb);
00260             }
00261             kc += k;
00262             ++k;
00263         } else {
00264 
00265 /*           2 x 2 diagonal block */
00266 
00267 /*           Multiply by inv(U'(K+1)), where U(K+1) is the transformation */
00268 /*           stored in columns K and K+1 of A. */
00269 
00270             i__1 = k - 1;
00271             sgemv_("Transpose", &i__1, nrhs, &c_b7, &b[b_offset], ldb, &ap[kc]
00272 , &c__1, &c_b19, &b[k + b_dim1], ldb);
00273             i__1 = k - 1;
00274             sgemv_("Transpose", &i__1, nrhs, &c_b7, &b[b_offset], ldb, &ap[kc 
00275                     + k], &c__1, &c_b19, &b[k + 1 + b_dim1], ldb);
00276 
00277 /*           Interchange rows K and -IPIV(K). */
00278 
00279             kp = -ipiv[k];
00280             if (kp != k) {
00281                 sswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], ldb);
00282             }
00283             kc = kc + (k << 1) + 1;
00284             k += 2;
00285         }
00286 
00287         goto L40;
00288 L50:
00289 
00290         ;
00291     } else {
00292 
00293 /*        Solve A*X = B, where A = L*D*L'. */
00294 
00295 /*        First solve L*D*X = B, overwriting B with X. */
00296 
00297 /*        K is the main loop index, increasing from 1 to N in steps of */
00298 /*        1 or 2, depending on the size of the diagonal blocks. */
00299 
00300         k = 1;
00301         kc = 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, &ap[kc + 1], &c__1, &b[k + b_dim1], 
00327                         ldb, &b[k + 1 + b_dim1], ldb);
00328             }
00329 
00330 /*           Multiply by the inverse of the diagonal block. */
00331 
00332             r__1 = 1.f / ap[kc];
00333             sscal_(nrhs, &r__1, &b[k + b_dim1], ldb);
00334             kc = kc + *n - k + 1;
00335             ++k;
00336         } else {
00337 
00338 /*           2 x 2 diagonal block */
00339 
00340 /*           Interchange rows K+1 and -IPIV(K). */
00341 
00342             kp = -ipiv[k];
00343             if (kp != k + 1) {
00344                 sswap_(nrhs, &b[k + 1 + b_dim1], ldb, &b[kp + b_dim1], ldb);
00345             }
00346 
00347 /*           Multiply by inv(L(K)), where L(K) is the transformation */
00348 /*           stored in columns K and K+1 of A. */
00349 
00350             if (k < *n - 1) {
00351                 i__1 = *n - k - 1;
00352                 sger_(&i__1, nrhs, &c_b7, &ap[kc + 2], &c__1, &b[k + b_dim1], 
00353                         ldb, &b[k + 2 + b_dim1], ldb);
00354                 i__1 = *n - k - 1;
00355                 sger_(&i__1, nrhs, &c_b7, &ap[kc + *n - k + 2], &c__1, &b[k + 
00356                         1 + b_dim1], ldb, &b[k + 2 + b_dim1], ldb);
00357             }
00358 
00359 /*           Multiply by the inverse of the diagonal block. */
00360 
00361             akm1k = ap[kc + 1];
00362             akm1 = ap[kc] / akm1k;
00363             ak = ap[kc + *n - k + 1] / akm1k;
00364             denom = akm1 * ak - 1.f;
00365             i__1 = *nrhs;
00366             for (j = 1; j <= i__1; ++j) {
00367                 bkm1 = b[k + j * b_dim1] / akm1k;
00368                 bk = b[k + 1 + j * b_dim1] / akm1k;
00369                 b[k + j * b_dim1] = (ak * bkm1 - bk) / denom;
00370                 b[k + 1 + j * b_dim1] = (akm1 * bk - bkm1) / denom;
00371 /* L70: */
00372             }
00373             kc = kc + (*n - k << 1) + 1;
00374             k += 2;
00375         }
00376 
00377         goto L60;
00378 L80:
00379 
00380 /*        Next solve L'*X = B, overwriting B with X. */
00381 
00382 /*        K is the main loop index, decreasing from N to 1 in steps of */
00383 /*        1 or 2, depending on the size of the diagonal blocks. */
00384 
00385         k = *n;
00386         kc = *n * (*n + 1) / 2 + 1;
00387 L90:
00388 
00389 /*        If K < 1, exit from loop. */
00390 
00391         if (k < 1) {
00392             goto L100;
00393         }
00394 
00395         kc -= *n - k + 1;
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                 sgemv_("Transpose", &i__1, nrhs, &c_b7, &b[k + 1 + b_dim1], 
00406                         ldb, &ap[kc + 1], &c__1, &c_b19, &b[k + b_dim1], ldb);
00407             }
00408 
00409 /*           Interchange rows K and IPIV(K). */
00410 
00411             kp = ipiv[k];
00412             if (kp != k) {
00413                 sswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], ldb);
00414             }
00415             --k;
00416         } else {
00417 
00418 /*           2 x 2 diagonal block */
00419 
00420 /*           Multiply by inv(L'(K-1)), where L(K-1) is the transformation */
00421 /*           stored in columns K-1 and K of A. */
00422 
00423             if (k < *n) {
00424                 i__1 = *n - k;
00425                 sgemv_("Transpose", &i__1, nrhs, &c_b7, &b[k + 1 + b_dim1], 
00426                         ldb, &ap[kc + 1], &c__1, &c_b19, &b[k + b_dim1], ldb);
00427                 i__1 = *n - k;
00428                 sgemv_("Transpose", &i__1, nrhs, &c_b7, &b[k + 1 + b_dim1], 
00429                         ldb, &ap[kc - (*n - k)], &c__1, &c_b19, &b[k - 1 + 
00430                         b_dim1], ldb);
00431             }
00432 
00433 /*           Interchange rows K and -IPIV(K). */
00434 
00435             kp = -ipiv[k];
00436             if (kp != k) {
00437                 sswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], ldb);
00438             }
00439             kc -= *n - k + 2;
00440             k += -2;
00441         }
00442 
00443         goto L90;
00444 L100:
00445         ;
00446     }
00447 
00448     return 0;
00449 
00450 /*     End of SSPTRS */
00451 
00452 } /* ssptrs_ */


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