1 SUBROUTINE DSYTRD
( UPLO
, N
, A
, LDA
, D
, E
, TAU
, WORK
, LWORK
, INFO
)
3 * -- LAPACK routine
(version
3.1) --
4 * Univ
. of Tennessee
, Univ
. of California Berkeley and NAG Ltd
..
7 * .. Scalar Arguments
..
9 INTEGER INFO
, LDA
, LWORK
, N
11 * .. Array Arguments
..
12 DOUBLE PRECISION A
( LDA
, * ), D
( * ), E
( * ), TAU
( * ),
19 * DSYTRD reduces a
real symmetric matrix A
to real symmetric
20 * tridiagonal form T by an orthogonal similarity transformation
:
26 * UPLO
(input
) CHARACTER*1
27 * = 'U': Upper triangle of A is stored
;
28 * = 'L': Lower triangle of A is stored
.
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 * WORK
(workspace
/output
) DOUBLE PRECISION array
, dimension (MAX
(1,LWORK
))
68 * On exit
, if INFO
= 0, WORK
(1) returns the optimal LWORK
.
70 * LWORK
(input
) INTEGER
71 * The
dimension of the array WORK
. LWORK
>= 1.
72 * For optimum performance LWORK
>= N*NB
, where NB is the
75 * If LWORK
= -1, then a workspace query is assumed
; the routine
76 * only calculates the optimal size of the WORK array
, returns
77 * this value as the first entry of the WORK array
, and no error
78 * message related
to LWORK is issued by XERBLA
.
80 * INFO
(output
) INTEGER
81 * = 0: successful exit
82 * < 0: if INFO
= -i
, the i
-th argument had an illegal value
87 * If UPLO
= 'U', the matrix Q is represented as a product of elementary
90 * Q
= H
(n
-1) . . . H
(2) H
(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(i+1:n) = 0 and v(i) = 1; v(1:i-1) is stored on exit in
98 * A(1:i-1,i+1), and tau in TAU(i).
100 * If UPLO = 'L
', the matrix Q is represented as a product of elementary
103 * Q = H(1) H(2) . . . H(n-1).
105 * Each H(i) has the form
107 * H(i) = I - tau * v * v'
109 * where tau is a
real scalar
, and v is a
real vector with
110 * v
(1:i
) = 0 and v
(i
+1) = 1; v
(i
+2:n
) is stored on exit in A
(i
+2:n
,i
),
113 * The contents of A on exit are illustrated by the following examples
116 * if UPLO
= 'U': if UPLO
= 'L':
118 * ( d e v2 v3 v4
) ( d
)
119 * ( d e v3 v4
) ( e d
)
120 * ( d e v4
) ( v1 e d
)
121 * ( d e
) ( v1 v2 e d
)
122 * ( d
) ( v1 v2 v3 e d
)
124 * where d and e denote diagonal and off
-diagonal elements of T
, and vi
125 * denotes an element of the vector defining H
(i
).
127 * =====================================================================
131 PARAMETER ( ONE
= 1.0D
+0 )
133 * .. Local Scalars
..
134 LOGICAL LQUERY
, UPPER
135 INTEGER I
, IINFO
, IWS
, J
, KK
, LDWORK
, LWKOPT
, NB
,
138 * .. External Subroutines
..
139 EXTERNAL DLATRD
, DSYR2K
, DSYTD2
, XERBLA
141 * .. Intrinsic Functions
..
144 * .. External Functions
..
147 EXTERNAL LSAME
, ILAENV
149 * .. Executable Statements
..
151 * Test the input parameters
154 UPPER
= LSAME
( UPLO
, 'U' )
155 LQUERY
= ( LWORK
.EQ
.-1 )
156 IF( .NOT
.UPPER
.AND
. .NOT
.LSAME
( UPLO
, 'L' ) ) THEN
158 ELSE IF( N
.LT
.0 ) THEN
160 ELSE IF( LDA
.LT
.MAX
( 1, N
) ) THEN
162 ELSE IF( LWORK
.LT
.1 .AND
. .NOT
.LQUERY
) THEN
168 * Determine the block size
.
170 NB
= ILAENV
( 1, 'DSYTRD', UPLO
, N
, -1, -1, -1 )
176 CALL XERBLA
( 'DSYTRD', -INFO
)
178 ELSE IF( LQUERY
) THEN
182 * Quick
return if possible
191 IF( NB
.GT
.1 .AND
. NB
.LT
.N
) THEN
193 * Determine when
to cross over from blocked
to unblocked code
194 * (last block is always handled by unblocked code
).
196 NX
= MAX
( NB
, ILAENV
( 3, 'DSYTRD', UPLO
, N
, -1, -1, -1 ) )
199 * Determine
if workspace is large enough
for blocked code
.
203 IF( LWORK
.LT
.IWS
) THEN
205 * Not enough workspace
to use optimal NB
: determine the
206 * minimum value of NB
, and reduce NB or force use of
207 * unblocked code by setting NX
= N
.
209 NB
= MAX
( LWORK
/ LDWORK
, 1 )
210 NBMIN
= ILAENV
( 2, 'DSYTRD', UPLO
, N
, -1, -1, -1 )
223 * Reduce the upper triangle of A
.
224 * Columns
1:kk are handled by the unblocked method
.
226 KK
= N
- ( ( N
-NX
+NB
-1 ) / NB
)*NB
227 DO 20 I
= N
- NB
+ 1, KK
+ 1, -NB
229 * Reduce columns i
:i
+nb
-1 to tridiagonal form and form the
230 * matrix W which is needed
to update the unreduced part of
233 CALL DLATRD
( UPLO
, I
+NB
-1, NB
, A
, LDA
, E
, TAU
, WORK
,
236 * Update the unreduced submatrix A
(1:i
-1,1:i
-1), using an
237 * update of the form
: A
:= A
- V*W
' - W*V'
239 CALL DSYR2K
( UPLO
, 'No transpose', I
-1, NB
, -ONE
, A
( 1, I
),
240 $ LDA
, WORK
, LDWORK
, ONE
, A
, LDA
)
242 * Copy superdiagonal elements back into A
, and diagonal
245 DO 10 J
= I
, I
+ NB
- 1
246 A
( J
-1, J
) = E
( J
-1 )
251 * Use unblocked code
to reduce the last or only block
253 CALL DSYTD2
( UPLO
, KK
, A
, LDA
, D
, E
, TAU
, IINFO
)
256 * Reduce the lower triangle of A
258 DO 40 I
= 1, N
- NX
, NB
260 * Reduce columns i
:i
+nb
-1 to tridiagonal form and form the
261 * matrix W which is needed
to update the unreduced part of
264 CALL DLATRD
( UPLO
, N
-I
+1, NB
, A
( I
, I
), LDA
, E
( I
),
265 $ TAU
( I
), WORK
, LDWORK
)
267 * Update the unreduced submatrix A
(i
+ib
:n
,i
+ib
:n
), using
268 * an update of the form
: A
:= A
- V*W
' - W*V'
270 CALL DSYR2K
( UPLO
, 'No transpose', N
-I
-NB
+1, NB
, -ONE
,
271 $ A
( I
+NB
, I
), LDA
, WORK
( NB
+1 ), LDWORK
, ONE
,
272 $ A
( I
+NB
, I
+NB
), LDA
)
274 * Copy subdiagonal elements back into A
, and diagonal
277 DO 30 J
= I
, I
+ NB
- 1
283 * Use unblocked code
to reduce the last or only block
285 CALL DSYTD2
( UPLO
, N
-I
+1, A
( I
, I
), LDA
, D
( I
), E
( I
),