csptrs.c
Go to the documentation of this file.
00001 /* csptrs.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 csptrs_(char *uplo, integer *n, integer *nrhs, complex *
00022         ap, integer *ipiv, complex *b, integer *ldb, integer *info)
00023 {
00024     /* System generated locals */
00025     integer b_dim1, b_offset, i__1, i__2;
00026     complex q__1, q__2, q__3;
00027 
00028     /* Builtin functions */
00029     void c_div(complex *, complex *, complex *);
00030 
00031     /* Local variables */
00032     integer j, k;
00033     complex ak, bk;
00034     integer kc, kp;
00035     complex akm1, bkm1, akm1k;
00036     extern /* Subroutine */ int cscal_(integer *, complex *, complex *, 
00037             integer *);
00038     extern logical lsame_(char *, char *);
00039     complex denom;
00040     extern /* Subroutine */ int cgemv_(char *, integer *, integer *, complex *
00041 , complex *, integer *, complex *, integer *, complex *, complex *
00042 , integer *), cgeru_(integer *, integer *, complex *, 
00043             complex *, integer *, complex *, integer *, complex *, integer *),
00044              cswap_(integer *, complex *, integer *, complex *, integer *);
00045     logical upper;
00046     extern /* Subroutine */ int xerbla_(char *, integer *);
00047 
00048 
00049 /*  -- LAPACK routine (version 3.2) -- */
00050 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00051 /*     November 2006 */
00052 
00053 /*     .. Scalar Arguments .. */
00054 /*     .. */
00055 /*     .. Array Arguments .. */
00056 /*     .. */
00057 
00058 /*  Purpose */
00059 /*  ======= */
00060 
00061 /*  CSPTRS solves a system of linear equations A*X = B with a complex */
00062 /*  symmetric matrix A stored in packed format using the factorization */
00063 /*  A = U*D*U**T or A = L*D*L**T computed by CSPTRF. */
00064 
00065 /*  Arguments */
00066 /*  ========= */
00067 
00068 /*  UPLO    (input) CHARACTER*1 */
00069 /*          Specifies whether the details of the factorization are stored */
00070 /*          as an upper or lower triangular matrix. */
00071 /*          = 'U':  Upper triangular, form is A = U*D*U**T; */
00072 /*          = 'L':  Lower triangular, form is A = L*D*L**T. */
00073 
00074 /*  N       (input) INTEGER */
00075 /*          The order of the matrix A.  N >= 0. */
00076 
00077 /*  NRHS    (input) INTEGER */
00078 /*          The number of right hand sides, i.e., the number of columns */
00079 /*          of the matrix B.  NRHS >= 0. */
00080 
00081 /*  AP      (input) COMPLEX array, dimension (N*(N+1)/2) */
00082 /*          The block diagonal matrix D and the multipliers used to */
00083 /*          obtain the factor U or L as computed by CSPTRF, stored as a */
00084 /*          packed triangular matrix. */
00085 
00086 /*  IPIV    (input) INTEGER array, dimension (N) */
00087 /*          Details of the interchanges and the block structure of D */
00088 /*          as determined by CSPTRF. */
00089 
00090 /*  B       (input/output) COMPLEX 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     --ap;
00117     --ipiv;
00118     b_dim1 = *ldb;
00119     b_offset = 1 + b_dim1;
00120     b -= b_offset;
00121 
00122     /* Function Body */
00123     *info = 0;
00124     upper = lsame_(uplo, "U");
00125     if (! upper && ! lsame_(uplo, "L")) {
00126         *info = -1;
00127     } else if (*n < 0) {
00128         *info = -2;
00129     } else if (*nrhs < 0) {
00130         *info = -3;
00131     } else if (*ldb < max(1,*n)) {
00132         *info = -7;
00133     }
00134     if (*info != 0) {
00135         i__1 = -(*info);
00136         xerbla_("CSPTRS", &i__1);
00137         return 0;
00138     }
00139 
00140 /*     Quick return if possible */
00141 
00142     if (*n == 0 || *nrhs == 0) {
00143         return 0;
00144     }
00145 
00146     if (upper) {
00147 
00148 /*        Solve A*X = B, where A = U*D*U'. */
00149 
00150 /*        First solve U*D*X = B, overwriting B with X. */
00151 
00152 /*        K is the main loop index, decreasing from N to 1 in steps of */
00153 /*        1 or 2, depending on the size of the diagonal blocks. */
00154 
00155         k = *n;
00156         kc = *n * (*n + 1) / 2 + 1;
00157 L10:
00158 
00159 /*        If K < 1, exit from loop. */
00160 
00161         if (k < 1) {
00162             goto L30;
00163         }
00164 
00165         kc -= k;
00166         if (ipiv[k] > 0) {
00167 
00168 /*           1 x 1 diagonal block */
00169 
00170 /*           Interchange rows K and IPIV(K). */
00171 
00172             kp = ipiv[k];
00173             if (kp != k) {
00174                 cswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], ldb);
00175             }
00176 
00177 /*           Multiply by inv(U(K)), where U(K) is the transformation */
00178 /*           stored in column K of A. */
00179 
00180             i__1 = k - 1;
00181             q__1.r = -1.f, q__1.i = -0.f;
00182             cgeru_(&i__1, nrhs, &q__1, &ap[kc], &c__1, &b[k + b_dim1], ldb, &
00183                     b[b_dim1 + 1], ldb);
00184 
00185 /*           Multiply by the inverse of the diagonal block. */
00186 
00187             c_div(&q__1, &c_b1, &ap[kc + k - 1]);
00188             cscal_(nrhs, &q__1, &b[k + b_dim1], ldb);
00189             --k;
00190         } else {
00191 
00192 /*           2 x 2 diagonal block */
00193 
00194 /*           Interchange rows K-1 and -IPIV(K). */
00195 
00196             kp = -ipiv[k];
00197             if (kp != k - 1) {
00198                 cswap_(nrhs, &b[k - 1 + b_dim1], ldb, &b[kp + b_dim1], ldb);
00199             }
00200 
00201 /*           Multiply by inv(U(K)), where U(K) is the transformation */
00202 /*           stored in columns K-1 and K of A. */
00203 
00204             i__1 = k - 2;
00205             q__1.r = -1.f, q__1.i = -0.f;
00206             cgeru_(&i__1, nrhs, &q__1, &ap[kc], &c__1, &b[k + b_dim1], ldb, &
00207                     b[b_dim1 + 1], ldb);
00208             i__1 = k - 2;
00209             q__1.r = -1.f, q__1.i = -0.f;
00210             cgeru_(&i__1, nrhs, &q__1, &ap[kc - (k - 1)], &c__1, &b[k - 1 + 
00211                     b_dim1], ldb, &b[b_dim1 + 1], ldb);
00212 
00213 /*           Multiply by the inverse of the diagonal block. */
00214 
00215             i__1 = kc + k - 2;
00216             akm1k.r = ap[i__1].r, akm1k.i = ap[i__1].i;
00217             c_div(&q__1, &ap[kc - 1], &akm1k);
00218             akm1.r = q__1.r, akm1.i = q__1.i;
00219             c_div(&q__1, &ap[kc + k - 1], &akm1k);
00220             ak.r = q__1.r, ak.i = q__1.i;
00221             q__2.r = akm1.r * ak.r - akm1.i * ak.i, q__2.i = akm1.r * ak.i + 
00222                     akm1.i * ak.r;
00223             q__1.r = q__2.r - 1.f, q__1.i = q__2.i - 0.f;
00224             denom.r = q__1.r, denom.i = q__1.i;
00225             i__1 = *nrhs;
00226             for (j = 1; j <= i__1; ++j) {
00227                 c_div(&q__1, &b[k - 1 + j * b_dim1], &akm1k);
00228                 bkm1.r = q__1.r, bkm1.i = q__1.i;
00229                 c_div(&q__1, &b[k + j * b_dim1], &akm1k);
00230                 bk.r = q__1.r, bk.i = q__1.i;
00231                 i__2 = k - 1 + j * b_dim1;
00232                 q__3.r = ak.r * bkm1.r - ak.i * bkm1.i, q__3.i = ak.r * 
00233                         bkm1.i + ak.i * bkm1.r;
00234                 q__2.r = q__3.r - bk.r, q__2.i = q__3.i - bk.i;
00235                 c_div(&q__1, &q__2, &denom);
00236                 b[i__2].r = q__1.r, b[i__2].i = q__1.i;
00237                 i__2 = k + j * b_dim1;
00238                 q__3.r = akm1.r * bk.r - akm1.i * bk.i, q__3.i = akm1.r * 
00239                         bk.i + akm1.i * bk.r;
00240                 q__2.r = q__3.r - bkm1.r, q__2.i = q__3.i - bkm1.i;
00241                 c_div(&q__1, &q__2, &denom);
00242                 b[i__2].r = q__1.r, b[i__2].i = q__1.i;
00243 /* L20: */
00244             }
00245             kc = kc - k + 1;
00246             k += -2;
00247         }
00248 
00249         goto L10;
00250 L30:
00251 
00252 /*        Next solve U'*X = B, overwriting B with X. */
00253 
00254 /*        K is the main loop index, increasing from 1 to N in steps of */
00255 /*        1 or 2, depending on the size of the diagonal blocks. */
00256 
00257         k = 1;
00258         kc = 1;
00259 L40:
00260 
00261 /*        If K > N, exit from loop. */
00262 
00263         if (k > *n) {
00264             goto L50;
00265         }
00266 
00267         if (ipiv[k] > 0) {
00268 
00269 /*           1 x 1 diagonal block */
00270 
00271 /*           Multiply by inv(U'(K)), where U(K) is the transformation */
00272 /*           stored in column K of A. */
00273 
00274             i__1 = k - 1;
00275             q__1.r = -1.f, q__1.i = -0.f;
00276             cgemv_("Transpose", &i__1, nrhs, &q__1, &b[b_offset], ldb, &ap[kc]
00277 , &c__1, &c_b1, &b[k + b_dim1], ldb);
00278 
00279 /*           Interchange rows K and IPIV(K). */
00280 
00281             kp = ipiv[k];
00282             if (kp != k) {
00283                 cswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], ldb);
00284             }
00285             kc += k;
00286             ++k;
00287         } else {
00288 
00289 /*           2 x 2 diagonal block */
00290 
00291 /*           Multiply by inv(U'(K+1)), where U(K+1) is the transformation */
00292 /*           stored in columns K and K+1 of A. */
00293 
00294             i__1 = k - 1;
00295             q__1.r = -1.f, q__1.i = -0.f;
00296             cgemv_("Transpose", &i__1, nrhs, &q__1, &b[b_offset], ldb, &ap[kc]
00297 , &c__1, &c_b1, &b[k + b_dim1], ldb);
00298             i__1 = k - 1;
00299             q__1.r = -1.f, q__1.i = -0.f;
00300             cgemv_("Transpose", &i__1, nrhs, &q__1, &b[b_offset], ldb, &ap[kc 
00301                     + k], &c__1, &c_b1, &b[k + 1 + b_dim1], ldb);
00302 
00303 /*           Interchange rows K and -IPIV(K). */
00304 
00305             kp = -ipiv[k];
00306             if (kp != k) {
00307                 cswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], ldb);
00308             }
00309             kc = kc + (k << 1) + 1;
00310             k += 2;
00311         }
00312 
00313         goto L40;
00314 L50:
00315 
00316         ;
00317     } else {
00318 
00319 /*        Solve A*X = B, where A = L*D*L'. */
00320 
00321 /*        First solve L*D*X = B, overwriting B with X. */
00322 
00323 /*        K is the main loop index, increasing from 1 to N in steps of */
00324 /*        1 or 2, depending on the size of the diagonal blocks. */
00325 
00326         k = 1;
00327         kc = 1;
00328 L60:
00329 
00330 /*        If K > N, exit from loop. */
00331 
00332         if (k > *n) {
00333             goto L80;
00334         }
00335 
00336         if (ipiv[k] > 0) {
00337 
00338 /*           1 x 1 diagonal block */
00339 
00340 /*           Interchange rows K and IPIV(K). */
00341 
00342             kp = ipiv[k];
00343             if (kp != k) {
00344                 cswap_(nrhs, &b[k + 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 column K of A. */
00349 
00350             if (k < *n) {
00351                 i__1 = *n - k;
00352                 q__1.r = -1.f, q__1.i = -0.f;
00353                 cgeru_(&i__1, nrhs, &q__1, &ap[kc + 1], &c__1, &b[k + b_dim1], 
00354                          ldb, &b[k + 1 + b_dim1], ldb);
00355             }
00356 
00357 /*           Multiply by the inverse of the diagonal block. */
00358 
00359             c_div(&q__1, &c_b1, &ap[kc]);
00360             cscal_(nrhs, &q__1, &b[k + b_dim1], ldb);
00361             kc = kc + *n - k + 1;
00362             ++k;
00363         } else {
00364 
00365 /*           2 x 2 diagonal block */
00366 
00367 /*           Interchange rows K+1 and -IPIV(K). */
00368 
00369             kp = -ipiv[k];
00370             if (kp != k + 1) {
00371                 cswap_(nrhs, &b[k + 1 + b_dim1], ldb, &b[kp + b_dim1], ldb);
00372             }
00373 
00374 /*           Multiply by inv(L(K)), where L(K) is the transformation */
00375 /*           stored in columns K and K+1 of A. */
00376 
00377             if (k < *n - 1) {
00378                 i__1 = *n - k - 1;
00379                 q__1.r = -1.f, q__1.i = -0.f;
00380                 cgeru_(&i__1, nrhs, &q__1, &ap[kc + 2], &c__1, &b[k + b_dim1], 
00381                          ldb, &b[k + 2 + b_dim1], ldb);
00382                 i__1 = *n - k - 1;
00383                 q__1.r = -1.f, q__1.i = -0.f;
00384                 cgeru_(&i__1, nrhs, &q__1, &ap[kc + *n - k + 2], &c__1, &b[k 
00385                         + 1 + b_dim1], ldb, &b[k + 2 + b_dim1], ldb);
00386             }
00387 
00388 /*           Multiply by the inverse of the diagonal block. */
00389 
00390             i__1 = kc + 1;
00391             akm1k.r = ap[i__1].r, akm1k.i = ap[i__1].i;
00392             c_div(&q__1, &ap[kc], &akm1k);
00393             akm1.r = q__1.r, akm1.i = q__1.i;
00394             c_div(&q__1, &ap[kc + *n - k + 1], &akm1k);
00395             ak.r = q__1.r, ak.i = q__1.i;
00396             q__2.r = akm1.r * ak.r - akm1.i * ak.i, q__2.i = akm1.r * ak.i + 
00397                     akm1.i * ak.r;
00398             q__1.r = q__2.r - 1.f, q__1.i = q__2.i - 0.f;
00399             denom.r = q__1.r, denom.i = q__1.i;
00400             i__1 = *nrhs;
00401             for (j = 1; j <= i__1; ++j) {
00402                 c_div(&q__1, &b[k + j * b_dim1], &akm1k);
00403                 bkm1.r = q__1.r, bkm1.i = q__1.i;
00404                 c_div(&q__1, &b[k + 1 + j * b_dim1], &akm1k);
00405                 bk.r = q__1.r, bk.i = q__1.i;
00406                 i__2 = k + j * b_dim1;
00407                 q__3.r = ak.r * bkm1.r - ak.i * bkm1.i, q__3.i = ak.r * 
00408                         bkm1.i + ak.i * bkm1.r;
00409                 q__2.r = q__3.r - bk.r, q__2.i = q__3.i - bk.i;
00410                 c_div(&q__1, &q__2, &denom);
00411                 b[i__2].r = q__1.r, b[i__2].i = q__1.i;
00412                 i__2 = k + 1 + j * b_dim1;
00413                 q__3.r = akm1.r * bk.r - akm1.i * bk.i, q__3.i = akm1.r * 
00414                         bk.i + akm1.i * bk.r;
00415                 q__2.r = q__3.r - bkm1.r, q__2.i = q__3.i - bkm1.i;
00416                 c_div(&q__1, &q__2, &denom);
00417                 b[i__2].r = q__1.r, b[i__2].i = q__1.i;
00418 /* L70: */
00419             }
00420             kc = kc + (*n - k << 1) + 1;
00421             k += 2;
00422         }
00423 
00424         goto L60;
00425 L80:
00426 
00427 /*        Next solve L'*X = B, overwriting B with X. */
00428 
00429 /*        K is the main loop index, decreasing from N to 1 in steps of */
00430 /*        1 or 2, depending on the size of the diagonal blocks. */
00431 
00432         k = *n;
00433         kc = *n * (*n + 1) / 2 + 1;
00434 L90:
00435 
00436 /*        If K < 1, exit from loop. */
00437 
00438         if (k < 1) {
00439             goto L100;
00440         }
00441 
00442         kc -= *n - k + 1;
00443         if (ipiv[k] > 0) {
00444 
00445 /*           1 x 1 diagonal block */
00446 
00447 /*           Multiply by inv(L'(K)), where L(K) is the transformation */
00448 /*           stored in column K of A. */
00449 
00450             if (k < *n) {
00451                 i__1 = *n - k;
00452                 q__1.r = -1.f, q__1.i = -0.f;
00453                 cgemv_("Transpose", &i__1, nrhs, &q__1, &b[k + 1 + b_dim1], 
00454                         ldb, &ap[kc + 1], &c__1, &c_b1, &b[k + b_dim1], ldb);
00455             }
00456 
00457 /*           Interchange rows K and IPIV(K). */
00458 
00459             kp = ipiv[k];
00460             if (kp != k) {
00461                 cswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], ldb);
00462             }
00463             --k;
00464         } else {
00465 
00466 /*           2 x 2 diagonal block */
00467 
00468 /*           Multiply by inv(L'(K-1)), where L(K-1) is the transformation */
00469 /*           stored in columns K-1 and K of A. */
00470 
00471             if (k < *n) {
00472                 i__1 = *n - k;
00473                 q__1.r = -1.f, q__1.i = -0.f;
00474                 cgemv_("Transpose", &i__1, nrhs, &q__1, &b[k + 1 + b_dim1], 
00475                         ldb, &ap[kc + 1], &c__1, &c_b1, &b[k + b_dim1], ldb);
00476                 i__1 = *n - k;
00477                 q__1.r = -1.f, q__1.i = -0.f;
00478                 cgemv_("Transpose", &i__1, nrhs, &q__1, &b[k + 1 + b_dim1], 
00479                         ldb, &ap[kc - (*n - k)], &c__1, &c_b1, &b[k - 1 + 
00480                         b_dim1], ldb);
00481             }
00482 
00483 /*           Interchange rows K and -IPIV(K). */
00484 
00485             kp = -ipiv[k];
00486             if (kp != k) {
00487                 cswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], ldb);
00488             }
00489             kc -= *n - k + 2;
00490             k += -2;
00491         }
00492 
00493         goto L90;
00494 L100:
00495         ;
00496     }
00497 
00498     return 0;
00499 
00500 /*     End of CSPTRS */
00501 
00502 } /* csptrs_ */


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