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


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