slavsp.c
Go to the documentation of this file.
00001 /* slavsp.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 real c_b15 = 1.f;
00019 static integer c__1 = 1;
00020 
00021 /* Subroutine */ int slavsp_(char *uplo, char *trans, char *diag, integer *n, 
00022         integer *nrhs, real *a, integer *ipiv, real *b, integer *ldb, integer 
00023         *info)
00024 {
00025     /* System generated locals */
00026     integer b_dim1, b_offset, i__1;
00027 
00028     /* Local variables */
00029     integer j, k;
00030     real t1, t2, d11, d12, d21, d22;
00031     integer kc, kp;
00032     extern /* Subroutine */ int sger_(integer *, integer *, real *, real *, 
00033             integer *, real *, integer *, real *, integer *);
00034     extern logical lsame_(char *, char *);
00035     extern /* Subroutine */ int sscal_(integer *, real *, real *, integer *), 
00036             sgemv_(char *, integer *, integer *, real *, real *, integer *, 
00037             real *, integer *, real *, real *, integer *), sswap_(
00038             integer *, real *, integer *, real *, integer *), xerbla_(char *, 
00039             integer *);
00040     integer kcnext;
00041     logical nounit;
00042 
00043 
00044 /*  -- LAPACK auxiliary routine (version 3.1) -- */
00045 /*     Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */
00046 /*     November 2006 */
00047 
00048 /*     .. Scalar Arguments .. */
00049 /*     .. */
00050 /*     .. Array Arguments .. */
00051 /*     .. */
00052 
00053 /*  Purpose */
00054 /*  ======= */
00055 
00056 /*  SLAVSP  performs one of the matrix-vector operations */
00057 /*     x := A*x  or  x := A'*x, */
00058 /*  where x is an N element vector and  A is one of the factors */
00059 /*  from the block U*D*U' or L*D*L' factorization computed by SSPTRF. */
00060 
00061 /*  If TRANS = 'N', multiplies by U  or U * D  (or L  or L * D) */
00062 /*  If TRANS = 'T', multiplies by U' or D * U' (or L' or D * L' ) */
00063 /*  If TRANS = 'C', multiplies by U' or D * U' (or L' or D * L' ) */
00064 
00065 /*  Arguments */
00066 /*  ========== */
00067 
00068 /*  UPLO    (input) CHARACTER*1 */
00069 /*          Specifies whether the factor stored in A is upper or lower */
00070 /*          triangular. */
00071 /*          = 'U':  Upper triangular */
00072 /*          = 'L':  Lower triangular */
00073 
00074 /*  TRANS   (input) CHARACTER*1 */
00075 /*          Specifies the operation to be performed: */
00076 /*          = 'N':  x := A*x */
00077 /*          = 'T':  x := A'*x */
00078 /*          = 'C':  x := A'*x */
00079 
00080 /*  DIAG    (input) CHARACTER*1 */
00081 /*          Specifies whether or not the diagonal blocks are unit */
00082 /*          matrices.  If the diagonal blocks are assumed to be unit, */
00083 /*          then A = U or A = L, otherwise A = U*D or A = L*D. */
00084 /*          = 'U':  Diagonal blocks are assumed to be unit matrices. */
00085 /*          = 'N':  Diagonal blocks are assumed to be non-unit matrices. */
00086 
00087 /*  N       (input) INTEGER */
00088 /*          The number of rows and columns of the matrix A.  N >= 0. */
00089 
00090 /*  NRHS    (input) INTEGER */
00091 /*          The number of right hand sides, i.e., the number of vectors */
00092 /*          x to be multiplied by A.  NRHS >= 0. */
00093 
00094 /*  A       (input) REAL array, dimension (N*(N+1)/2) */
00095 /*          The block diagonal matrix D and the multipliers used to */
00096 /*          obtain the factor U or L, stored as a packed triangular */
00097 /*          matrix as computed by SSPTRF. */
00098 
00099 /*  IPIV    (input) INTEGER array, dimension (N) */
00100 /*          The pivot indices from SSPTRF. */
00101 
00102 /*  B       (input/output) REAL array, dimension (LDB,NRHS) */
00103 /*          On entry, B contains NRHS vectors of length N. */
00104 /*          On exit, B is overwritten with the product A * B. */
00105 
00106 /*  LDB     (input) INTEGER */
00107 /*          The leading dimension of the array B.  LDB >= max(1,N). */
00108 
00109 /*  INFO    (output) INTEGER */
00110 /*          = 0: successful exit */
00111 /*          < 0: if INFO = -k, the k-th argument had an illegal value */
00112 
00113 /*  ===================================================================== */
00114 
00115 /*     .. Parameters .. */
00116 /*     .. */
00117 /*     .. Local Scalars .. */
00118 /*     .. */
00119 /*     .. External Functions .. */
00120 /*     .. */
00121 /*     .. External Subroutines .. */
00122 /*     .. */
00123 /*     .. Intrinsic Functions .. */
00124 /*     .. */
00125 /*     .. Executable Statements .. */
00126 
00127 /*     Test the input parameters. */
00128 
00129     /* Parameter adjustments */
00130     --a;
00131     --ipiv;
00132     b_dim1 = *ldb;
00133     b_offset = 1 + b_dim1;
00134     b -= b_offset;
00135 
00136     /* Function Body */
00137     *info = 0;
00138     if (! lsame_(uplo, "U") && ! lsame_(uplo, "L")) {
00139         *info = -1;
00140     } else if (! lsame_(trans, "N") && ! lsame_(trans, 
00141             "T") && ! lsame_(trans, "C")) {
00142         *info = -2;
00143     } else if (! lsame_(diag, "U") && ! lsame_(diag, 
00144             "N")) {
00145         *info = -3;
00146     } else if (*n < 0) {
00147         *info = -4;
00148     } else if (*ldb < max(1,*n)) {
00149         *info = -8;
00150     }
00151     if (*info != 0) {
00152         i__1 = -(*info);
00153         xerbla_("SLAVSP ", &i__1);
00154         return 0;
00155     }
00156 
00157 /*     Quick return if possible. */
00158 
00159     if (*n == 0) {
00160         return 0;
00161     }
00162 
00163     nounit = lsame_(diag, "N");
00164 /* ------------------------------------------ */
00165 
00166 /*     Compute  B := A * B  (No transpose) */
00167 
00168 /* ------------------------------------------ */
00169     if (lsame_(trans, "N")) {
00170 
00171 /*        Compute  B := U*B */
00172 /*        where U = P(m)*inv(U(m))* ... *P(1)*inv(U(1)) */
00173 
00174         if (lsame_(uplo, "U")) {
00175 
00176 /*        Loop forward applying the transformations. */
00177 
00178             k = 1;
00179             kc = 1;
00180 L10:
00181             if (k > *n) {
00182                 goto L30;
00183             }
00184 
00185 /*           1 x 1 pivot block */
00186 
00187             if (ipiv[k] > 0) {
00188 
00189 /*              Multiply by the diagonal element if forming U * D. */
00190 
00191                 if (nounit) {
00192                     sscal_(nrhs, &a[kc + k - 1], &b[k + b_dim1], ldb);
00193                 }
00194 
00195 /*              Multiply by P(K) * inv(U(K))  if K > 1. */
00196 
00197                 if (k > 1) {
00198 
00199 /*                 Apply the transformation. */
00200 
00201                     i__1 = k - 1;
00202                     sger_(&i__1, nrhs, &c_b15, &a[kc], &c__1, &b[k + b_dim1], 
00203                             ldb, &b[b_dim1 + 1], ldb);
00204 
00205 /*                 Interchange if P(K) != I. */
00206 
00207                     kp = ipiv[k];
00208                     if (kp != k) {
00209                         sswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], 
00210                                 ldb);
00211                     }
00212                 }
00213                 kc += k;
00214                 ++k;
00215             } else {
00216 
00217 /*              2 x 2 pivot block */
00218 
00219                 kcnext = kc + k;
00220 
00221 /*              Multiply by the diagonal block if forming U * D. */
00222 
00223                 if (nounit) {
00224                     d11 = a[kcnext - 1];
00225                     d22 = a[kcnext + k];
00226                     d12 = a[kcnext + k - 1];
00227                     d21 = d12;
00228                     i__1 = *nrhs;
00229                     for (j = 1; j <= i__1; ++j) {
00230                         t1 = b[k + j * b_dim1];
00231                         t2 = b[k + 1 + j * b_dim1];
00232                         b[k + j * b_dim1] = d11 * t1 + d12 * t2;
00233                         b[k + 1 + j * b_dim1] = d21 * t1 + d22 * t2;
00234 /* L20: */
00235                     }
00236                 }
00237 
00238 /*              Multiply by  P(K) * inv(U(K))  if K > 1. */
00239 
00240                 if (k > 1) {
00241 
00242 /*                 Apply the transformations. */
00243 
00244                     i__1 = k - 1;
00245                     sger_(&i__1, nrhs, &c_b15, &a[kc], &c__1, &b[k + b_dim1], 
00246                             ldb, &b[b_dim1 + 1], ldb);
00247                     i__1 = k - 1;
00248                     sger_(&i__1, nrhs, &c_b15, &a[kcnext], &c__1, &b[k + 1 + 
00249                             b_dim1], ldb, &b[b_dim1 + 1], ldb);
00250 
00251 /*                 Interchange if P(K) != I. */
00252 
00253                     kp = (i__1 = ipiv[k], abs(i__1));
00254                     if (kp != k) {
00255                         sswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], 
00256                                 ldb);
00257                     }
00258                 }
00259                 kc = kcnext + k + 1;
00260                 k += 2;
00261             }
00262             goto L10;
00263 L30:
00264 
00265 /*        Compute  B := L*B */
00266 /*        where L = P(1)*inv(L(1))* ... *P(m)*inv(L(m)) . */
00267 
00268             ;
00269         } else {
00270 
00271 /*           Loop backward applying the transformations to B. */
00272 
00273             k = *n;
00274             kc = *n * (*n + 1) / 2 + 1;
00275 L40:
00276             if (k < 1) {
00277                 goto L60;
00278             }
00279             kc -= *n - k + 1;
00280 
00281 /*           Test the pivot index.  If greater than zero, a 1 x 1 */
00282 /*           pivot was used, otherwise a 2 x 2 pivot was used. */
00283 
00284             if (ipiv[k] > 0) {
00285 
00286 /*              1 x 1 pivot block: */
00287 
00288 /*              Multiply by the diagonal element if forming L * D. */
00289 
00290                 if (nounit) {
00291                     sscal_(nrhs, &a[kc], &b[k + b_dim1], ldb);
00292                 }
00293 
00294 /*              Multiply by  P(K) * inv(L(K))  if K < N. */
00295 
00296                 if (k != *n) {
00297                     kp = ipiv[k];
00298 
00299 /*                 Apply the transformation. */
00300 
00301                     i__1 = *n - k;
00302                     sger_(&i__1, nrhs, &c_b15, &a[kc + 1], &c__1, &b[k + 
00303                             b_dim1], ldb, &b[k + 1 + b_dim1], ldb);
00304 
00305 /*                 Interchange if a permutation was applied at the */
00306 /*                 K-th step of the factorization. */
00307 
00308                     if (kp != k) {
00309                         sswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], 
00310                                 ldb);
00311                     }
00312                 }
00313                 --k;
00314 
00315             } else {
00316 
00317 /*              2 x 2 pivot block: */
00318 
00319                 kcnext = kc - (*n - k + 2);
00320 
00321 /*              Multiply by the diagonal block if forming L * D. */
00322 
00323                 if (nounit) {
00324                     d11 = a[kcnext];
00325                     d22 = a[kc];
00326                     d21 = a[kcnext + 1];
00327                     d12 = d21;
00328                     i__1 = *nrhs;
00329                     for (j = 1; j <= i__1; ++j) {
00330                         t1 = b[k - 1 + j * b_dim1];
00331                         t2 = b[k + j * b_dim1];
00332                         b[k - 1 + j * b_dim1] = d11 * t1 + d12 * t2;
00333                         b[k + j * b_dim1] = d21 * t1 + d22 * t2;
00334 /* L50: */
00335                     }
00336                 }
00337 
00338 /*              Multiply by  P(K) * inv(L(K))  if K < N. */
00339 
00340                 if (k != *n) {
00341 
00342 /*                 Apply the transformation. */
00343 
00344                     i__1 = *n - k;
00345                     sger_(&i__1, nrhs, &c_b15, &a[kc + 1], &c__1, &b[k + 
00346                             b_dim1], ldb, &b[k + 1 + b_dim1], ldb);
00347                     i__1 = *n - k;
00348                     sger_(&i__1, nrhs, &c_b15, &a[kcnext + 2], &c__1, &b[k - 
00349                             1 + b_dim1], ldb, &b[k + 1 + b_dim1], ldb);
00350 
00351 /*                 Interchange if a permutation was applied at the */
00352 /*                 K-th step of the factorization. */
00353 
00354                     kp = (i__1 = ipiv[k], abs(i__1));
00355                     if (kp != k) {
00356                         sswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], 
00357                                 ldb);
00358                     }
00359                 }
00360                 kc = kcnext;
00361                 k += -2;
00362             }
00363             goto L40;
00364 L60:
00365             ;
00366         }
00367 /* ---------------------------------------- */
00368 
00369 /*     Compute  B := A' * B  (transpose) */
00370 
00371 /* ---------------------------------------- */
00372     } else {
00373 
00374 /*        Form  B := U'*B */
00375 /*        where U  = P(m)*inv(U(m))* ... *P(1)*inv(U(1)) */
00376 /*        and   U' = inv(U'(1))*P(1)* ... *inv(U'(m))*P(m) */
00377 
00378         if (lsame_(uplo, "U")) {
00379 
00380 /*           Loop backward applying the transformations. */
00381 
00382             k = *n;
00383             kc = *n * (*n + 1) / 2 + 1;
00384 L70:
00385             if (k < 1) {
00386                 goto L90;
00387             }
00388             kc -= k;
00389 
00390 /*           1 x 1 pivot block. */
00391 
00392             if (ipiv[k] > 0) {
00393                 if (k > 1) {
00394 
00395 /*                 Interchange if P(K) != I. */
00396 
00397                     kp = ipiv[k];
00398                     if (kp != k) {
00399                         sswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], 
00400                                 ldb);
00401                     }
00402 
00403 /*                 Apply the transformation */
00404 
00405                     i__1 = k - 1;
00406                     sgemv_("Transpose", &i__1, nrhs, &c_b15, &b[b_offset], 
00407                             ldb, &a[kc], &c__1, &c_b15, &b[k + b_dim1], ldb);
00408                 }
00409                 if (nounit) {
00410                     sscal_(nrhs, &a[kc + k - 1], &b[k + b_dim1], ldb);
00411                 }
00412                 --k;
00413 
00414 /*           2 x 2 pivot block. */
00415 
00416             } else {
00417                 kcnext = kc - (k - 1);
00418                 if (k > 2) {
00419 
00420 /*                 Interchange if P(K) != I. */
00421 
00422                     kp = (i__1 = ipiv[k], abs(i__1));
00423                     if (kp != k - 1) {
00424                         sswap_(nrhs, &b[k - 1 + b_dim1], ldb, &b[kp + b_dim1], 
00425                                  ldb);
00426                     }
00427 
00428 /*                 Apply the transformations */
00429 
00430                     i__1 = k - 2;
00431                     sgemv_("Transpose", &i__1, nrhs, &c_b15, &b[b_offset], 
00432                             ldb, &a[kc], &c__1, &c_b15, &b[k + b_dim1], ldb);
00433                     i__1 = k - 2;
00434                     sgemv_("Transpose", &i__1, nrhs, &c_b15, &b[b_offset], 
00435                             ldb, &a[kcnext], &c__1, &c_b15, &b[k - 1 + b_dim1]
00436 , ldb);
00437                 }
00438 
00439 /*              Multiply by the diagonal block if non-unit. */
00440 
00441                 if (nounit) {
00442                     d11 = a[kc - 1];
00443                     d22 = a[kc + k - 1];
00444                     d12 = a[kc + k - 2];
00445                     d21 = d12;
00446                     i__1 = *nrhs;
00447                     for (j = 1; j <= i__1; ++j) {
00448                         t1 = b[k - 1 + j * b_dim1];
00449                         t2 = b[k + j * b_dim1];
00450                         b[k - 1 + j * b_dim1] = d11 * t1 + d12 * t2;
00451                         b[k + j * b_dim1] = d21 * t1 + d22 * t2;
00452 /* L80: */
00453                     }
00454                 }
00455                 kc = kcnext;
00456                 k += -2;
00457             }
00458             goto L70;
00459 L90:
00460 
00461 /*        Form  B := L'*B */
00462 /*        where L  = P(1)*inv(L(1))* ... *P(m)*inv(L(m)) */
00463 /*        and   L' = inv(L(m))*P(m)* ... *inv(L(1))*P(1) */
00464 
00465             ;
00466         } else {
00467 
00468 /*           Loop forward applying the L-transformations. */
00469 
00470             k = 1;
00471             kc = 1;
00472 L100:
00473             if (k > *n) {
00474                 goto L120;
00475             }
00476 
00477 /*           1 x 1 pivot block */
00478 
00479             if (ipiv[k] > 0) {
00480                 if (k < *n) {
00481 
00482 /*                 Interchange if P(K) != I. */
00483 
00484                     kp = ipiv[k];
00485                     if (kp != k) {
00486                         sswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], 
00487                                 ldb);
00488                     }
00489 
00490 /*                 Apply the transformation */
00491 
00492                     i__1 = *n - k;
00493                     sgemv_("Transpose", &i__1, nrhs, &c_b15, &b[k + 1 + 
00494                             b_dim1], ldb, &a[kc + 1], &c__1, &c_b15, &b[k + 
00495                             b_dim1], ldb);
00496                 }
00497                 if (nounit) {
00498                     sscal_(nrhs, &a[kc], &b[k + b_dim1], ldb);
00499                 }
00500                 kc = kc + *n - k + 1;
00501                 ++k;
00502 
00503 /*           2 x 2 pivot block. */
00504 
00505             } else {
00506                 kcnext = kc + *n - k + 1;
00507                 if (k < *n - 1) {
00508 
00509 /*              Interchange if P(K) != I. */
00510 
00511                     kp = (i__1 = ipiv[k], abs(i__1));
00512                     if (kp != k + 1) {
00513                         sswap_(nrhs, &b[k + 1 + b_dim1], ldb, &b[kp + b_dim1], 
00514                                  ldb);
00515                     }
00516 
00517 /*                 Apply the transformation */
00518 
00519                     i__1 = *n - k - 1;
00520                     sgemv_("Transpose", &i__1, nrhs, &c_b15, &b[k + 2 + 
00521                             b_dim1], ldb, &a[kcnext + 1], &c__1, &c_b15, &b[k 
00522                             + 1 + b_dim1], ldb);
00523                     i__1 = *n - k - 1;
00524                     sgemv_("Transpose", &i__1, nrhs, &c_b15, &b[k + 2 + 
00525                             b_dim1], ldb, &a[kc + 2], &c__1, &c_b15, &b[k + 
00526                             b_dim1], ldb);
00527                 }
00528 
00529 /*              Multiply by the diagonal block if non-unit. */
00530 
00531                 if (nounit) {
00532                     d11 = a[kc];
00533                     d22 = a[kcnext];
00534                     d21 = a[kc + 1];
00535                     d12 = d21;
00536                     i__1 = *nrhs;
00537                     for (j = 1; j <= i__1; ++j) {
00538                         t1 = b[k + j * b_dim1];
00539                         t2 = b[k + 1 + j * b_dim1];
00540                         b[k + j * b_dim1] = d11 * t1 + d12 * t2;
00541                         b[k + 1 + j * b_dim1] = d21 * t1 + d22 * t2;
00542 /* L110: */
00543                     }
00544                 }
00545                 kc = kcnext + (*n - k);
00546                 k += 2;
00547             }
00548             goto L100;
00549 L120:
00550             ;
00551         }
00552 
00553     }
00554     return 0;
00555 
00556 /*     End of SLAVSP */
00557 
00558 } /* slavsp_ */


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