/* dlavsy.f -- translated by f2c (version 20061008). You must link the resulting object file with libf2c: on Microsoft Windows system, link with libf2c.lib; on Linux or Unix systems, link with .../path/to/libf2c.a -lm or, if you install libf2c.a in a standard place, with -lf2c -lm -- in that order, at the end of the command line, as in cc *.o -lf2c -lm Source for libf2c is in /netlib/f2c/libf2c.zip, e.g., http://www.netlib.org/f2c/libf2c.zip */ #include "f2c.h" #include "blaswrap.h" /* Table of constant values */ static doublereal c_b15 = 1.; static integer c__1 = 1; /* Subroutine */ int dlavsy_(char *uplo, char *trans, char *diag, integer *n, integer *nrhs, doublereal *a, integer *lda, integer *ipiv, doublereal *b, integer *ldb, integer *info) { /* System generated locals */ integer a_dim1, a_offset, b_dim1, b_offset, i__1; /* Local variables */ integer j, k; doublereal t1, t2, d11, d12, d21, d22; integer kp; extern /* Subroutine */ int dger_(integer *, integer *, doublereal *, doublereal *, integer *, doublereal *, integer *, doublereal *, integer *), dscal_(integer *, doublereal *, doublereal *, integer *); extern logical lsame_(char *, char *); extern /* Subroutine */ int dgemv_(char *, integer *, integer *, doublereal *, doublereal *, integer *, doublereal *, integer *, doublereal *, doublereal *, integer *), dswap_(integer *, doublereal *, integer *, doublereal *, integer *), xerbla_(char *, integer *); logical nounit; /* -- LAPACK auxiliary routine (version 3.1) -- */ /* Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd.. */ /* November 2006 */ /* .. Scalar Arguments .. */ /* .. */ /* .. Array Arguments .. */ /* .. */ /* Purpose */ /* ======= */ /* DLAVSY performs one of the matrix-vector operations */ /* x := A*x or x := A'*x, */ /* where x is an N element vector and A is one of the factors */ /* from the block U*D*U' or L*D*L' factorization computed by DSYTRF. */ /* If TRANS = 'N', multiplies by U or U * D (or L or L * D) */ /* If TRANS = 'T', multiplies by U' or D * U' (or L' or D * L') */ /* If TRANS = 'C', multiplies by U' or D * U' (or L' or D * L') */ /* Arguments */ /* ========= */ /* UPLO (input) CHARACTER*1 */ /* Specifies whether the factor stored in A is upper or lower */ /* triangular. */ /* = 'U': Upper triangular */ /* = 'L': Lower triangular */ /* TRANS (input) CHARACTER*1 */ /* Specifies the operation to be performed: */ /* = 'N': x := A*x */ /* = 'T': x := A'*x */ /* = 'C': x := A'*x */ /* DIAG (input) CHARACTER*1 */ /* Specifies whether or not the diagonal blocks are unit */ /* matrices. If the diagonal blocks are assumed to be unit, */ /* then A = U or A = L, otherwise A = U*D or A = L*D. */ /* = 'U': Diagonal blocks are assumed to be unit matrices. */ /* = 'N': Diagonal blocks are assumed to be non-unit matrices. */ /* N (input) INTEGER */ /* The number of rows and columns of the matrix A. N >= 0. */ /* NRHS (input) INTEGER */ /* The number of right hand sides, i.e., the number of vectors */ /* x to be multiplied by A. NRHS >= 0. */ /* A (input) DOUBLE PRECISION array, dimension (LDA,N) */ /* The block diagonal matrix D and the multipliers used to */ /* obtain the factor U or L as computed by DSYTRF. */ /* LDA (input) INTEGER */ /* The leading dimension of the array A. LDA >= max(1,N). */ /* IPIV (input) INTEGER array, dimension (N) */ /* The pivot indices from DSYTRF. */ /* B (input/output) DOUBLE PRECISION array, dimension (LDB,NRHS) */ /* On entry, B contains NRHS vectors of length N. */ /* On exit, B is overwritten with the product A * B. */ /* LDB (input) INTEGER */ /* The leading dimension of the array B. LDB >= max(1,N). */ /* INFO (output) INTEGER */ /* = 0: successful exit */ /* < 0: if INFO = -k, the k-th argument had an illegal value */ /* ===================================================================== */ /* .. Parameters .. */ /* .. */ /* .. Local Scalars .. */ /* .. */ /* .. External Functions .. */ /* .. */ /* .. External Subroutines .. */ /* .. */ /* .. Intrinsic Functions .. */ /* .. */ /* .. Executable Statements .. */ /* Test the input parameters. */ /* Parameter adjustments */ a_dim1 = *lda; a_offset = 1 + a_dim1; a -= a_offset; --ipiv; b_dim1 = *ldb; b_offset = 1 + b_dim1; b -= b_offset; /* Function Body */ *info = 0; if (! lsame_(uplo, "U") && ! lsame_(uplo, "L")) { *info = -1; } else if (! lsame_(trans, "N") && ! lsame_(trans, "T") && ! lsame_(trans, "C")) { *info = -2; } else if (! lsame_(diag, "U") && ! lsame_(diag, "N")) { *info = -3; } else if (*n < 0) { *info = -4; } else if (*lda < max(1,*n)) { *info = -6; } else if (*ldb < max(1,*n)) { *info = -9; } if (*info != 0) { i__1 = -(*info); xerbla_("DLAVSY ", &i__1); return 0; } /* Quick return if possible. */ if (*n == 0) { return 0; } nounit = lsame_(diag, "N"); /* ------------------------------------------ */ /* Compute B := A * B (No transpose) */ /* ------------------------------------------ */ if (lsame_(trans, "N")) { /* Compute B := U*B */ /* where U = P(m)*inv(U(m))* ... *P(1)*inv(U(1)) */ if (lsame_(uplo, "U")) { /* Loop forward applying the transformations. */ k = 1; L10: if (k > *n) { goto L30; } if (ipiv[k] > 0) { /* 1 x 1 pivot block */ /* Multiply by the diagonal element if forming U * D. */ if (nounit) { dscal_(nrhs, &a[k + k * a_dim1], &b[k + b_dim1], ldb); } /* Multiply by P(K) * inv(U(K)) if K > 1. */ if (k > 1) { /* Apply the transformation. */ i__1 = k - 1; dger_(&i__1, nrhs, &c_b15, &a[k * a_dim1 + 1], &c__1, &b[ k + b_dim1], ldb, &b[b_dim1 + 1], ldb); /* Interchange if P(K) .ne. I. */ kp = ipiv[k]; if (kp != k) { dswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], ldb); } } ++k; } else { /* 2 x 2 pivot block */ /* Multiply by the diagonal block if forming U * D. */ if (nounit) { d11 = a[k + k * a_dim1]; d22 = a[k + 1 + (k + 1) * a_dim1]; d12 = a[k + (k + 1) * a_dim1]; d21 = d12; i__1 = *nrhs; for (j = 1; j <= i__1; ++j) { t1 = b[k + j * b_dim1]; t2 = b[k + 1 + j * b_dim1]; b[k + j * b_dim1] = d11 * t1 + d12 * t2; b[k + 1 + j * b_dim1] = d21 * t1 + d22 * t2; /* L20: */ } } /* Multiply by P(K) * inv(U(K)) if K > 1. */ if (k > 1) { /* Apply the transformations. */ i__1 = k - 1; dger_(&i__1, nrhs, &c_b15, &a[k * a_dim1 + 1], &c__1, &b[ k + b_dim1], ldb, &b[b_dim1 + 1], ldb); i__1 = k - 1; dger_(&i__1, nrhs, &c_b15, &a[(k + 1) * a_dim1 + 1], & c__1, &b[k + 1 + b_dim1], ldb, &b[b_dim1 + 1], ldb); /* Interchange if P(K) .ne. I. */ kp = (i__1 = ipiv[k], abs(i__1)); if (kp != k) { dswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], ldb); } } k += 2; } goto L10; L30: /* Compute B := L*B */ /* where L = P(1)*inv(L(1))* ... *P(m)*inv(L(m)) . */ ; } else { /* Loop backward applying the transformations to B. */ k = *n; L40: if (k < 1) { goto L60; } /* Test the pivot index. If greater than zero, a 1 x 1 */ /* pivot was used, otherwise a 2 x 2 pivot was used. */ if (ipiv[k] > 0) { /* 1 x 1 pivot block: */ /* Multiply by the diagonal element if forming L * D. */ if (nounit) { dscal_(nrhs, &a[k + k * a_dim1], &b[k + b_dim1], ldb); } /* Multiply by P(K) * inv(L(K)) if K < N. */ if (k != *n) { kp = ipiv[k]; /* Apply the transformation. */ i__1 = *n - k; dger_(&i__1, nrhs, &c_b15, &a[k + 1 + k * a_dim1], &c__1, &b[k + b_dim1], ldb, &b[k + 1 + b_dim1], ldb); /* Interchange if a permutation was applied at the */ /* K-th step of the factorization. */ if (kp != k) { dswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], ldb); } } --k; } else { /* 2 x 2 pivot block: */ /* Multiply by the diagonal block if forming L * D. */ if (nounit) { d11 = a[k - 1 + (k - 1) * a_dim1]; d22 = a[k + k * a_dim1]; d21 = a[k + (k - 1) * a_dim1]; d12 = d21; i__1 = *nrhs; for (j = 1; j <= i__1; ++j) { t1 = b[k - 1 + j * b_dim1]; t2 = b[k + j * b_dim1]; b[k - 1 + j * b_dim1] = d11 * t1 + d12 * t2; b[k + j * b_dim1] = d21 * t1 + d22 * t2; /* L50: */ } } /* Multiply by P(K) * inv(L(K)) if K < N. */ if (k != *n) { /* Apply the transformation. */ i__1 = *n - k; dger_(&i__1, nrhs, &c_b15, &a[k + 1 + k * a_dim1], &c__1, &b[k + b_dim1], ldb, &b[k + 1 + b_dim1], ldb); i__1 = *n - k; dger_(&i__1, nrhs, &c_b15, &a[k + 1 + (k - 1) * a_dim1], & c__1, &b[k - 1 + b_dim1], ldb, &b[k + 1 + b_dim1], ldb); /* Interchange if a permutation was applied at the */ /* K-th step of the factorization. */ kp = (i__1 = ipiv[k], abs(i__1)); if (kp != k) { dswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], ldb); } } k += -2; } goto L40; L60: ; } /* ---------------------------------------- */ /* Compute B := A' * B (transpose) */ /* ---------------------------------------- */ } else { /* Form B := U'*B */ /* where U = P(m)*inv(U(m))* ... *P(1)*inv(U(1)) */ /* and U' = inv(U'(1))*P(1)* ... *inv(U'(m))*P(m) */ if (lsame_(uplo, "U")) { /* Loop backward applying the transformations. */ k = *n; L70: if (k < 1) { goto L90; } /* 1 x 1 pivot block. */ if (ipiv[k] > 0) { if (k > 1) { /* Interchange if P(K) .ne. I. */ kp = ipiv[k]; if (kp != k) { dswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], ldb); } /* Apply the transformation */ i__1 = k - 1; dgemv_("Transpose", &i__1, nrhs, &c_b15, &b[b_offset], ldb, &a[k * a_dim1 + 1], &c__1, &c_b15, &b[k + b_dim1], ldb); } if (nounit) { dscal_(nrhs, &a[k + k * a_dim1], &b[k + b_dim1], ldb); } --k; /* 2 x 2 pivot block. */ } else { if (k > 2) { /* Interchange if P(K) .ne. I. */ kp = (i__1 = ipiv[k], abs(i__1)); if (kp != k - 1) { dswap_(nrhs, &b[k - 1 + b_dim1], ldb, &b[kp + b_dim1], ldb); } /* Apply the transformations */ i__1 = k - 2; dgemv_("Transpose", &i__1, nrhs, &c_b15, &b[b_offset], ldb, &a[k * a_dim1 + 1], &c__1, &c_b15, &b[k + b_dim1], ldb); i__1 = k - 2; dgemv_("Transpose", &i__1, nrhs, &c_b15, &b[b_offset], ldb, &a[(k - 1) * a_dim1 + 1], &c__1, &c_b15, &b[ k - 1 + b_dim1], ldb); } /* Multiply by the diagonal block if non-unit. */ if (nounit) { d11 = a[k - 1 + (k - 1) * a_dim1]; d22 = a[k + k * a_dim1]; d12 = a[k - 1 + k * a_dim1]; d21 = d12; i__1 = *nrhs; for (j = 1; j <= i__1; ++j) { t1 = b[k - 1 + j * b_dim1]; t2 = b[k + j * b_dim1]; b[k - 1 + j * b_dim1] = d11 * t1 + d12 * t2; b[k + j * b_dim1] = d21 * t1 + d22 * t2; /* L80: */ } } k += -2; } goto L70; L90: /* Form B := L'*B */ /* where L = P(1)*inv(L(1))* ... *P(m)*inv(L(m)) */ /* and L' = inv(L'(m))*P(m)* ... *inv(L'(1))*P(1) */ ; } else { /* Loop forward applying the L-transformations. */ k = 1; L100: if (k > *n) { goto L120; } /* 1 x 1 pivot block */ if (ipiv[k] > 0) { if (k < *n) { /* Interchange if P(K) .ne. I. */ kp = ipiv[k]; if (kp != k) { dswap_(nrhs, &b[k + b_dim1], ldb, &b[kp + b_dim1], ldb); } /* Apply the transformation */ i__1 = *n - k; dgemv_("Transpose", &i__1, nrhs, &c_b15, &b[k + 1 + b_dim1], ldb, &a[k + 1 + k * a_dim1], &c__1, & c_b15, &b[k + b_dim1], ldb); } if (nounit) { dscal_(nrhs, &a[k + k * a_dim1], &b[k + b_dim1], ldb); } ++k; /* 2 x 2 pivot block. */ } else { if (k < *n - 1) { /* Interchange if P(K) .ne. I. */ kp = (i__1 = ipiv[k], abs(i__1)); if (kp != k + 1) { dswap_(nrhs, &b[k + 1 + b_dim1], ldb, &b[kp + b_dim1], ldb); } /* Apply the transformation */ i__1 = *n - k - 1; dgemv_("Transpose", &i__1, nrhs, &c_b15, &b[k + 2 + b_dim1], ldb, &a[k + 2 + (k + 1) * a_dim1], &c__1, &c_b15, &b[k + 1 + b_dim1], ldb); i__1 = *n - k - 1; dgemv_("Transpose", &i__1, nrhs, &c_b15, &b[k + 2 + b_dim1], ldb, &a[k + 2 + k * a_dim1], &c__1, & c_b15, &b[k + b_dim1], ldb); } /* Multiply by the diagonal block if non-unit. */ if (nounit) { d11 = a[k + k * a_dim1]; d22 = a[k + 1 + (k + 1) * a_dim1]; d21 = a[k + 1 + k * a_dim1]; d12 = d21; i__1 = *nrhs; for (j = 1; j <= i__1; ++j) { t1 = b[k + j * b_dim1]; t2 = b[k + 1 + j * b_dim1]; b[k + j * b_dim1] = d11 * t1 + d12 * t2; b[k + 1 + j * b_dim1] = d21 * t1 + d22 * t2; /* L110: */ } } k += 2; } goto L100; L120: ; } } return 0; /* End of DLAVSY */ } /* dlavsy_ */