2
3
4
5
6
7
8 INTEGER INFO, K, LDA, N
9
10
11 INTEGER ISEED( 4 )
12 DOUBLE PRECISION D( * )
13 COMPLEX*16 A( LDA, * ), WORK( * )
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 COMPLEX*16 ZERO, ONE, HALF
60 parameter( zero = ( 0.0d+0, 0.0d+0 ),
61 $ one = ( 1.0d+0, 0.0d+0 ),
62 $ half = ( 0.5d+0, 0.0d+0 ) )
63
64
65 INTEGER I, J
66 DOUBLE PRECISION WN
67 COMPLEX*16 ALPHA, TAU, WA, WB
68
69
72
73
74 DOUBLE PRECISION DZNRM2
75 COMPLEX*16 ZDOTC
77
78
79 INTRINSIC abs, dble, dconjg,
max
80
81
82
83
84
85 info = 0
86 IF( n.LT.0 ) THEN
87 info = -1
88 ELSE IF( k.LT.0 .OR. k.GT.n-1 ) THEN
89 info = -2
90 ELSE IF( lda.LT.
max( 1, n ) )
THEN
91 info = -5
92 END IF
93 IF( info.LT.0 ) THEN
94 CALL xerbla(
'ZLAGHE', -info )
95 RETURN
96 END IF
97
98
99
100 DO 20 j = 1, n
101 DO 10 i = j + 1, n
102 a( i, j ) = zero
103 10 CONTINUE
104 20 CONTINUE
105 DO 30 i = 1, n
106 a( i, i ) = d( i )
107 30 CONTINUE
108
109
110
111 DO 40 i = n - 1, 1, -1
112
113
114
115 CALL zlarnv( 3, iseed, n-i+1, work )
116 wn =
dznrm2( n-i+1, work, 1 )
117 wa = ( wn / abs( work( 1 ) ) )*work( 1 )
118 IF( wn.EQ.zero ) THEN
119 tau = zero
120 ELSE
121 wb = work( 1 ) + wa
122 CALL zscal( n-i, one / wb, work( 2 ), 1 )
123 work( 1 ) = one
124 tau = dble( wb / wa )
125 END IF
126
127
128
129
130
131
132 CALL zhemv(
'Lower', n-i+1, tau, a( i, i ), lda, work, 1, zero,
133 $ work( n+1 ), 1 )
134
135
136
137 alpha = -half*tau*
zdotc( n-i+1, work( n+1 ), 1, work, 1 )
138 CALL zaxpy( n-i+1,
alpha, work, 1, work( n+1 ), 1 )
139
140
141
142 CALL zher2(
'Lower', n-i+1, -one, work, 1, work( n+1 ), 1,
143 $ a( i, i ), lda )
144 40 CONTINUE
145
146
147
148 DO 60 i = 1, n - 1 - k
149
150
151
152 wn =
dznrm2( n-k-i+1, a( k+i, i ), 1 )
153 wa = ( wn / abs( a( k+i, i ) ) )*a( k+i, i )
154 IF( wn.EQ.zero ) THEN
155 tau = zero
156 ELSE
157 wb = a( k+i, i ) + wa
158 CALL zscal( n-k-i, one / wb, a( k+i+1, i ), 1 )
159 a( k+i, i ) = one
160 tau = dble( wb / wa )
161 END IF
162
163
164
165 CALL zgemv(
'Conjugate transpose', n-k-i+1, k-1, one,
166 $ a( k+i, i+1 ), lda, a( k+i, i ), 1, zero, work, 1 )
167 CALL zgerc( n-k-i+1, k-1, -tau, a( k+i, i ), 1, work, 1,
168 $ a( k+i, i+1 ), lda )
169
170
171
172
173
174 CALL zhemv(
'Lower', n-k-i+1, tau, a( k+i, k+i ), lda,
175 $ a( k+i, i ), 1, zero, work, 1 )
176
177
178
179 alpha = -half*tau*
zdotc( n-k-i+1, work, 1, a( k+i, i ), 1 )
180 CALL zaxpy( n-k-i+1,
alpha, a( k+i, i ), 1, work, 1 )
181
182
183
184 CALL zher2(
'Lower', n-k-i+1, -one, a( k+i, i ), 1, work, 1,
185 $ a( k+i, k+i ), lda )
186
187 a( k+i, i ) = -wa
188 DO 50 j = k + i + 1, n
189 a( j, i ) = zero
190 50 CONTINUE
191 60 CONTINUE
192
193
194
195 DO 80 j = 1, n
196 DO 70 i = j + 1, n
197 a( j, i ) = dconjg( a( i, j ) )
198 70 CONTINUE
199 80 CONTINUE
200 RETURN
201
202
203
subroutine xerbla(srname, info)
XERBLA
subroutine zlarnv(idist, iseed, n, x)
ZLARNV returns a vector of random numbers from a uniform or normal distribution.
complex *16 function zdotc(n, zx, incx, zy, incy)
ZDOTC
subroutine zaxpy(n, za, zx, incx, zy, incy)
ZAXPY
subroutine zscal(n, za, zx, incx)
ZSCAL
subroutine zher2(uplo, n, alpha, x, incx, y, incy, a, lda)
ZHER2
subroutine zgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
ZGEMV
subroutine zhemv(uplo, n, alpha, a, lda, x, incx, beta, y, incy)
ZHEMV
subroutine zgerc(m, n, alpha, x, incx, y, incy, a, lda)
ZGERC
real(wp) function dznrm2(n, x, incx)
DZNRM2