1 SUBROUTINE ZHETRD
( 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 D
( * ), E
( * )
13 COMPLEX*16 A
( LDA
, * ), TAU
( * ), WORK
( * )
19 * ZHETRD reduces a
complex Hermitian matrix A
to real symmetric
20 * tridiagonal form T by a unitary 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
) COMPLEX*16 array
, dimension (LDA
,N
)
34 * On entry
, the Hermitian 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 unitary
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 unitary 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
) COMPLEX*16 array
, dimension (N
-1)
64 * The scalar factors of the elementary reflectors
(see Further
67 * WORK
(workspace
/output
) COMPLEX*16 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 complex scalar, and v is a complex 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
complex scalar
, and v is a
complex 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 PARAMETER ( CONE
= ( 1.0D
+0, 0.0D
+0 ) )
135 * .. Local Scalars
..
136 LOGICAL LQUERY
, UPPER
137 INTEGER I
, IINFO
, IWS
, J
, KK
, LDWORK
, LWKOPT
, NB
,
140 * .. External Subroutines
..
141 EXTERNAL XERBLA
, ZHER2K
, ZHETD2
, ZLATRD
143 * .. Intrinsic Functions
..
146 * .. External Functions
..
149 EXTERNAL LSAME
, ILAENV
151 * .. Executable Statements
..
153 * Test the input parameters
156 UPPER
= LSAME
( UPLO
, 'U' )
157 LQUERY
= ( LWORK
.EQ
.-1 )
158 IF( .NOT
.UPPER
.AND
. .NOT
.LSAME
( UPLO
, 'L' ) ) THEN
160 ELSE IF( N
.LT
.0 ) THEN
162 ELSE IF( LDA
.LT
.MAX
( 1, N
) ) THEN
164 ELSE IF( LWORK
.LT
.1 .AND
. .NOT
.LQUERY
) THEN
170 * Determine the block size
.
172 NB
= ILAENV
( 1, 'ZHETRD', UPLO
, N
, -1, -1, -1 )
178 CALL XERBLA
( 'ZHETRD', -INFO
)
180 ELSE IF( LQUERY
) THEN
184 * Quick
return if possible
193 IF( NB
.GT
.1 .AND
. NB
.LT
.N
) THEN
195 * Determine when
to cross over from blocked
to unblocked code
196 * (last block is always handled by unblocked code
).
198 NX
= MAX
( NB
, ILAENV
( 3, 'ZHETRD', UPLO
, N
, -1, -1, -1 ) )
201 * Determine
if workspace is large enough
for blocked code
.
205 IF( LWORK
.LT
.IWS
) THEN
207 * Not enough workspace
to use optimal NB
: determine the
208 * minimum value of NB
, and reduce NB or force use of
209 * unblocked code by setting NX
= N
.
211 NB
= MAX
( LWORK
/ LDWORK
, 1 )
212 NBMIN
= ILAENV
( 2, 'ZHETRD', UPLO
, N
, -1, -1, -1 )
225 * Reduce the upper triangle of A
.
226 * Columns
1:kk are handled by the unblocked method
.
228 KK
= N
- ( ( N
-NX
+NB
-1 ) / NB
)*NB
229 DO 20 I
= N
- NB
+ 1, KK
+ 1, -NB
231 * Reduce columns i
:i
+nb
-1 to tridiagonal form and form the
232 * matrix W which is needed
to update the unreduced part of
235 CALL ZLATRD
( UPLO
, I
+NB
-1, NB
, A
, LDA
, E
, TAU
, WORK
,
238 * Update the unreduced submatrix A
(1:i
-1,1:i
-1), using an
239 * update of the form
: A
:= A
- V*W
' - W*V'
241 CALL ZHER2K
( UPLO
, 'No transpose', I
-1, NB
, -CONE
,
242 $ A
( 1, I
), LDA
, WORK
, LDWORK
, ONE
, A
, LDA
)
244 * Copy superdiagonal elements back into A
, and diagonal
247 DO 10 J
= I
, I
+ NB
- 1
248 A
( J
-1, J
) = E
( J
-1 )
253 * Use unblocked code
to reduce the last or only block
255 CALL ZHETD2
( UPLO
, KK
, A
, LDA
, D
, E
, TAU
, IINFO
)
258 * Reduce the lower triangle of A
260 DO 40 I
= 1, N
- NX
, NB
262 * Reduce columns i
:i
+nb
-1 to tridiagonal form and form the
263 * matrix W which is needed
to update the unreduced part of
266 CALL ZLATRD
( UPLO
, N
-I
+1, NB
, A
( I
, I
), LDA
, E
( I
),
267 $ TAU
( I
), WORK
, LDWORK
)
269 * Update the unreduced submatrix A
(i
+nb
:n
,i
+nb
:n
), using
270 * an update of the form
: A
:= A
- V*W
' - W*V'
272 CALL ZHER2K
( UPLO
, 'No transpose', N
-I
-NB
+1, NB
, -CONE
,
273 $ A
( I
+NB
, I
), LDA
, WORK
( NB
+1 ), LDWORK
, ONE
,
274 $ A
( I
+NB
, I
+NB
), LDA
)
276 * Copy subdiagonal elements back into A
, and diagonal
279 DO 30 J
= I
, I
+ NB
- 1
285 * Use unblocked code
to reduce the last or only block
287 CALL ZHETD2
( UPLO
, N
-I
+1, A
( I
, I
), LDA
, D
( I
), E
( I
),