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 + -
显示快捷键?