2
3
4
5
6
7
8 INTEGER INFO, K, LDA, N
9
10
11 INTEGER ISEED( 4 )
12 REAL D( * )
13 COMPLEX 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 ZERO, ONE, HALF
60 parameter( zero = ( 0.0e+0, 0.0e+0 ),
61 $ one = ( 1.0e+0, 0.0e+0 ),
62 $ half = ( 0.5e+0, 0.0e+0 ) )
63
64
65 INTEGER I, J
66 REAL WN
67 COMPLEX ALPHA, TAU, WA, WB
68
69
72
73
74 REAL SCNRM2
75 COMPLEX CDOTC
77
78
79 INTRINSIC abs, conjg,
max, real
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(
'CLAGHE', -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 clarnv( 3, iseed, n-i+1, work )
116 wn =
scnrm2( 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 cscal( n-i, one / wb, work( 2 ), 1 )
123 work( 1 ) = one
124 tau = real( wb / wa )
125 END IF
126
127
128
129
130
131
132 CALL chemv(
'Lower', n-i+1, tau, a( i, i ), lda, work, 1, zero,
133 $ work( n+1 ), 1 )
134
135
136
137 alpha = -half*tau*
cdotc( n-i+1, work( n+1 ), 1, work, 1 )
138 CALL caxpy( n-i+1,
alpha, work, 1, work( n+1 ), 1 )
139
140
141
142 CALL cher2(
'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 =
scnrm2( 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 cscal( n-k-i, one / wb, a( k+i+1, i ), 1 )
159 a( k+i, i ) = one
160 tau = real( wb / wa )
161 END IF
162
163
164
165 CALL cgemv(
'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 cgerc( 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 chemv(
'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*
cdotc( n-k-i+1, work, 1, a( k+i, i ), 1 )
180 CALL caxpy( n-k-i+1,
alpha, a( k+i, i ), 1, work, 1 )
181
182
183
184 CALL cher2(
'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 ) = conjg( a( i, j ) )
198 70 CONTINUE
199 80 CONTINUE
200 RETURN
201
202
203
subroutine xerbla(srname, info)
XERBLA
subroutine clarnv(idist, iseed, n, x)
CLARNV returns a vector of random numbers from a uniform or normal distribution.
subroutine caxpy(n, ca, cx, incx, cy, incy)
CAXPY
complex function cdotc(n, cx, incx, cy, incy)
CDOTC
subroutine cscal(n, ca, cx, incx)
CSCAL
subroutine chemv(uplo, n, alpha, a, lda, x, incx, beta, y, incy)
CHEMV
subroutine cgemv(trans, m, n, alpha, a, lda, x, incx, beta, y, incy)
CGEMV
subroutine cgerc(m, n, alpha, x, incx, y, incy, a, lda)
CGERC
subroutine cher2(uplo, n, alpha, x, incx, y, incy, a, lda)
CHER2
real(wp) function scnrm2(n, x, incx)
SCNRM2