1 SUBROUTINE DSYTD2( UPLO, N, A, LDA, D, E, TAU, INFO )
3 ! -- LAPACK routine (version 3.1) --
4 ! Univ. of Tennessee, Univ. of California Berkeley and NAG Ltd..
7 ! .. Scalar Arguments ..
11 ! .. Array Arguments ..
12 DOUBLE PRECISION A( LDA, * ), D( * ), E( * ), TAU( * )
18 ! DSYTD2 reduces a real symmetric matrix A to symmetric tridiagonal
19 ! form T by an orthogonal similarity transformation: Q' * A * Q = T.
24 ! UPLO (input) CHARACTER*1
25 ! Specifies whether the upper or lower triangular part of the
26 ! symmetric matrix A is stored:
27 ! = 'U': Upper triangular
28 ! = 'L': Lower triangular
31 ! The order of the matrix A. N >= 0.
33 ! A (input/output) DOUBLE PRECISION array, dimension (LDA,N)
34 ! On entry, the symmetric matrix A. If UPLO = 'U', the leading
35 ! n-by-n upper triangular part of A contains the upper
36 ! triangular part of the matrix A, and the strictly lower
37 ! triangular part of A is not referenced. If UPLO = 'L', the
38 ! leading n-by-n lower triangular part of A contains the lower
39 ! triangular part of the matrix A, and the strictly upper
40 ! triangular part of A is not referenced.
41 ! On exit, if UPLO = 'U', the diagonal and first superdiagonal
42 ! of A are overwritten by the corresponding elements of the
43 ! tridiagonal matrix T, and the elements above the first
44 ! superdiagonal, with the array TAU, represent the orthogonal
45 ! matrix Q as a product of elementary reflectors; if UPLO
46 ! = 'L', the diagonal and first subdiagonal of A are over-
47 ! written by the corresponding elements of the tridiagonal
48 ! matrix T, and the elements below the first subdiagonal, with
49 ! the array TAU, represent the orthogonal matrix Q as a product
50 ! of elementary reflectors. See Further Details.
53 ! The leading dimension of the array A. LDA >= max(1,N).
55 ! D (output) DOUBLE PRECISION array, dimension (N)
56 ! The diagonal elements of the tridiagonal matrix T:
59 ! E (output) DOUBLE PRECISION array, dimension (N-1)
60 ! The off-diagonal elements of the tridiagonal matrix T:
61 ! E(i) = A(i,i+1) if UPLO = 'U', E(i) = A(i+1,i) if UPLO = 'L'.
63 ! TAU (output) DOUBLE PRECISION array, dimension (N-1)
64 ! The scalar factors of the elementary reflectors (see Further
67 ! INFO (output) INTEGER
68 ! = 0: successful exit
69 ! < 0: if INFO = -i, the i-th argument had an illegal value.
74 ! If UPLO = 'U', the matrix Q is represented as a product of elementary
77 ! Q = H(n-1) . . . H(2) H(1).
79 ! Each H(i) has the form
81 ! H(i) = I - tau * v * v'
83 ! where tau is a real scalar, and v is a real vector with
84 ! v(i+1:n) = 0 and v(i) = 1; v(1:i-1) is stored on exit in
85 ! A(1:i-1,i+1), and tau in TAU(i).
87 ! If UPLO = 'L', the matrix Q is represented as a product of elementary
90 ! Q = H(1) H(2) . . . H(n-1).
92 ! Each H(i) has the form
94 ! H(i) = I - tau * v * v'
96 ! where tau is a real scalar, and v is a real vector with
97 ! v(1:i) = 0 and v(i+1) = 1; v(i+2:n) is stored on exit in A(i+2:n,i),
100 ! The contents of A on exit are illustrated by the following examples
103 ! if UPLO = 'U': if UPLO = 'L':
105 ! ( d e v2 v3 v4 ) ( d )
106 ! ( d e v3 v4 ) ( e d )
107 ! ( d e v4 ) ( v1 e d )
108 ! ( d e ) ( v1 v2 e d )
109 ! ( d ) ( v1 v2 v3 e d )
111 ! where d and e denote diagonal and off-diagonal elements of T, and vi
112 ! denotes an element of the vector defining H(i).
114 ! =====================================================================
117 DOUBLE PRECISION ONE, ZERO, HALF
118 PARAMETER ( ONE = 1.0D0, ZERO = 0.0D0, &
119 HALF = 1.0D0 / 2.0D0 )
121 ! .. Local Scalars ..
124 DOUBLE PRECISION ALPHA, TAUI
126 ! .. External Subroutines ..
127 ! EXTERNAL DAXPY, DLARFG, DSYMV, DSYR2, XERBLA
129 ! .. External Functions ..
131 ! DOUBLE PRECISION DDOT
132 ! EXTERNAL LSAME, DDOT
134 ! .. Intrinsic Functions ..
137 ! .. Executable Statements ..
139 ! Test the input parameters
142 UPPER = LSAME( UPLO, 'U' )
143 IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
145 ELSE IF( N.LT.0 ) THEN
147 ELSE IF( LDA.LT.MAX( 1, N ) ) THEN
151 CALL XERBLA( 'DSYTD2', -INFO )
155 ! Quick return if possible
162 ! Reduce the upper triangle of A
164 DO 10 I = N - 1, 1, -1
166 ! Generate elementary reflector H(i) = I - tau * v * v'
167 ! to annihilate A(1:i-1,i+1)
169 CALL DLARFG( I, A( I, I+1 ), A( 1, I+1 ), 1, TAUI )
172 IF( TAUI.NE.ZERO ) THEN
174 ! Apply H(i) from both sides to A(1:i,1:i)
178 ! Compute x := tau * A * v storing x in TAU(1:i)
180 CALL DSYMV( UPLO, I, TAUI, A, LDA, A( 1, I+1 ), 1, ZERO, &
183 ! Compute w := x - 1/2 * tau * (x'*v) * v
185 ALPHA = -HALF*TAUI*DDOT( I, TAU, 1, A( 1, I+1 ), 1 )
186 CALL DAXPY( I, ALPHA, A( 1, I+1 ), 1, TAU, 1 )
188 ! Apply the transformation as a rank-2 update:
189 ! A := A - v * w' - w * v'
191 CALL DSYR2( UPLO, I, -ONE, A( 1, I+1 ), 1, TAU, 1, A, &
196 D( I+1 ) = A( I+1, I+1 )
202 ! Reduce the lower triangle of A
206 ! Generate elementary reflector H(i) = I - tau * v * v'
207 ! to annihilate A(i+2:n,i)
209 CALL DLARFG( N-I, A( I+1, I ), A( MIN( I+2, N ), I ), 1, &
213 IF( TAUI.NE.ZERO ) THEN
215 ! Apply H(i) from both sides to A(i+1:n,i+1:n)
219 ! Compute x := tau * A * v storing y in TAU(i:n-1)
221 CALL DSYMV( UPLO, N-I, TAUI, A( I+1, I+1 ), LDA, &
222 A( I+1, I ), 1, ZERO, TAU( I ), 1 )
224 ! Compute w := x - 1/2 * tau * (x'*v) * v
226 ALPHA = -HALF*TAUI*DDOT( N-I, TAU( I ), 1, A( I+1, I ), &
228 CALL DAXPY( N-I, ALPHA, A( I+1, I ), 1, TAU( I ), 1 )
230 ! Apply the transformation as a rank-2 update:
231 ! A := A - v * w' - w * v'
233 CALL DSYR2( UPLO, N-I, -ONE, A( I+1, I ), 1, TAU( I ), 1, &
248 END SUBROUTINE DSYTD2