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


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