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


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