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


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