ssytd2.c
来自「NIST Handwriting OCR Testbed」· C语言 代码 · 共 296 行
C
296 行
/** ======================================================================* NIST Guide to Available Math Software.* Fullsource for module SSYEVX.C from package CLAPACK.* Retrieved from NETLIB on Fri Mar 10 14:23:44 2000.* ======================================================================*/#include <f2c.h>/* Subroutine */ int ssytd2_(char *uplo, integer *n, real *a, integer *lda, real *d, real *e, real *tau, integer *info){/* -- LAPACK routine (version 2.0) -- Univ. of Tennessee, Univ. of California Berkeley, NAG Ltd., Courant Institute, Argonne National Lab, and Rice University October 31, 1992 Purpose ======= SSYTD2 reduces a real symmetric matrix A to symmetric tridiagonal form T by an orthogonal similarity transformation: Q' * A * Q = T. Arguments ========= UPLO (input) CHARACTER*1 Specifies whether the upper or lower triangular part of the symmetric matrix A is stored: = 'U': Upper triangular = 'L': Lower triangular N (input) INTEGER The order of the matrix A. N >= 0. A (input/output) REAL array, dimension (LDA,N) On entry, the symmetric matrix A. If UPLO = 'U', the leading n-by-n upper triangular part of A contains the upper triangular part of the matrix A, and the strictly lower triangular part of A is not referenced. If UPLO = 'L', the leading n-by-n lower triangular part of A contains the lower triangular part of the matrix A, and the strictly upper triangular part of A is not referenced. On exit, if UPLO = 'U', the diagonal and first superdiagonal of A are overwritten by the corresponding elements of the tridiagonal matrix T, and the elements above the first superdiagonal, with the array TAU, represent the orthogonal matrix Q as a product of elementary reflectors; if UPLO = 'L', the diagonal and first subdiagonal of A are over- written by the corresponding elements of the tridiagonal matrix T, and the elements below the first subdiagonal, with the array TAU, represent the orthogonal matrix Q as a product of elementary reflectors. See Further Details. LDA (input) INTEGER The leading dimension of the array A. LDA >= max(1,N). D (output) REAL array, dimension (N) The diagonal elements of the tridiagonal matrix T: D(i) = A(i,i). E (output) REAL array, dimension (N-1) The off-diagonal elements of the tridiagonal matrix T: E(i) = A(i,i+1) if UPLO = 'U', E(i) = A(i+1,i) if UPLO = 'L'. TAU (output) REAL array, dimension (N-1) The scalar factors of the elementary reflectors (see Further Details). INFO (output) INTEGER = 0: successful exit < 0: if INFO = -i, the i-th argument had an illegal value. Further Details =============== If UPLO = 'U', the matrix Q is represented as a product of elementary reflectors Q = H(n-1) . . . H(2) H(1). Each H(i) has the form H(i) = I - tau * v * v' where tau is a real scalar, and v is a real vector with v(i+1:n) = 0 and v(i) = 1; v(1:i-1) is stored on exit in A(1:i-1,i+1), and tau in TAU(i). If UPLO = 'L', the matrix Q is represented as a product of elementary reflectors Q = H(1) H(2) . . . H(n-1). Each H(i) has the form H(i) = I - tau * v * v' where tau is a real scalar, and v is a real vector with v(1:i) = 0 and v(i+1) = 1; v(i+2:n) is stored on exit in A(i+2:n,i), and tau in TAU(i). The contents of A on exit are illustrated by the following examples with n = 5: if UPLO = 'U': if UPLO = 'L': ( d e v2 v3 v4 ) ( d ) ( d e v3 v4 ) ( e d ) ( d e v4 ) ( v1 e d ) ( d e ) ( v1 v2 e d ) ( d ) ( v1 v2 v3 e d ) where d and e denote diagonal and off-diagonal elements of T, and vi denotes an element of the vector defining H(i). ===================================================================== Test the input parameters Parameter adjustments Function Body */ /* Table of constant values */ static integer c__1 = 1; static real c_b8 = 0.f; static real c_b14 = -1.f; /* System generated locals */ integer a_dim1, a_offset, i__1, i__2, i__3; /* Local variables */ static real taui; extern doublereal sdot_(integer *, real *, integer *, real *, integer *); static integer i; extern /* Subroutine */ int ssyr2_(char *, integer *, real *, real *, integer *, real *, integer *, real *, integer *); static real alpha; extern logical lsame_(char *, char *); static logical upper; extern /* Subroutine */ int saxpy_(integer *, real *, real *, integer *, real *, integer *), ssymv_(char *, integer *, real *, real *, integer *, real *, integer *, real *, real *, integer *), xerbla_(char *, integer *), slarfg_(integer *, real *, real *, integer *, real *);int k;#define D(I) d[(I)-1]#define E(I) e[(I)-1]#define TAU(I) tau[(I)-1]#define A(I,J) a[(I)-1 + ((J)-1)* ( *lda)] *info = 0; upper = lsame_(uplo, "U"); if (! upper && ! lsame_(uplo, "L")) { *info = -1; } else if (*n < 0) { *info = -2; } else if (*lda < max(1,*n)) { *info = -4; } if (*info != 0) { i__1 = -(*info); xerbla_("SSYTD2", &i__1); return 0; }/* Quick return if possible */ if (*n <= 0) { return 0; } if (upper) {/* Reduce the upper triangle of A */ for (i = *n - 1; i >= 1; --i) {/* Generate elementary reflector H(i) = I - tau * v * v' to annihilate A(1:i-1,i+1) */ slarfg_(&i, &A(i,i+1), &A(1,i+1), & c__1, &taui); E(i) = A(i,i+1); if (taui != 0.f) {/* Apply H(i) from both sides to A(1:i,1:i) */ A(i,i+1) = 1.f;/* Compute x := tau * A * v storing x in TAU(1:i) */ ssymv_(uplo, &i, &taui, &A(1,1), lda, &A(1,i+1), &c__1, &c_b8, &TAU(1), &c__1);/* Compute w := x - 1/2 * tau * (x'*v) * v */ alpha = taui * -.5f * sdot_(&i, &TAU(1), &c__1, &A(1,i+1), &c__1); saxpy_(&i, &alpha, &A(1,i+1), &c__1, &TAU(1), & c__1);/* Apply the transformation as a rank-2 update: A := A - v * w' - w * v' */ ssyr2_(uplo, &i, &c_b14, &A(1,i+1), &c__1, & TAU(1), &c__1, &A(1,1), lda); A(i,i+1) = E(i); } D(i + 1) = A(i+1,i+1); TAU(i) = taui;/* L10: */ } D(1) = A(1,1); } else {/* Reduce the lower triangle of A */ i__1 = *n - 1; for (i = 1; i <= *n-1; ++i) {/* Generate elementary reflector H(i) = I - tau * v * v' to annihilate A(i+2:n,i) */ i__2 = *n - i;/* Computing MIN */ i__3 = i + 2; slarfg_(&i__2, &A(i+1,i), &A(min(i+2,*n),i), &c__1, &taui); E(i) = A(i+1,i); if (taui != 0.f) {/* Apply H(i) from both sides to A(i+1:n,i+1:n) */ A(i+1,i) = 1.f;/* Compute x := tau * A * v storing y in TAU(i:n-1) */ i__2 = *n - i; ssymv_(uplo, &i__2, &taui, &A(i+1,i+1), lda, &A(i+1,i), &c__1, &c_b8, &TAU(i), &c__1);/* Compute w := x - 1/2 * tau * (x'*v) * v */ i__2 = *n - i; alpha = taui * -.5f * sdot_(&i__2, &TAU(i), &c__1, &A(i+1,i), &c__1); i__2 = *n - i; saxpy_(&i__2, &alpha, &A(i+1,i), &c__1, &TAU(i), &c__1);/* Apply the transformation as a rank-2 update: A := A - v * w' - w * v' */ i__2 = *n - i; ssyr2_(uplo, &i__2, &c_b14, &A(i+1,i), &c__1, & TAU(i), &c__1, &A(i+1,i+1), lda); A(i+1,i) = E(i); } D(i) = A(i,i); TAU(i) = taui;/* L20: */ } D(*n) = A(*n,*n); } return 0;/* End of SSYTD2 */} /* ssytd2_ */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?