104
105
106
107
108
109
110 INTEGER INCX, N
111 COMPLEX*16 ALPHA, TAU
112
113
114 COMPLEX*16 X( * )
115
116
117
118
119
120 DOUBLE PRECISION TWO, ONE, ZERO
121 parameter( two = 2.0d+0, one = 1.0d+0, zero = 0.0d+0 )
122
123
124 INTEGER J, KNT
125 DOUBLE PRECISION ALPHI, ALPHR, BETA, BIGNUM, SMLNUM, XNORM
126 COMPLEX*16 SAVEALPHA
127
128
129 DOUBLE PRECISION DLAMCH, DLAPY3, DLAPY2, DZNRM2
130 COMPLEX*16 ZLADIV
132
133
134 INTRINSIC abs, dble, dcmplx, dimag, sign
135
136
138
139
140
141 IF( n.LE.0 ) THEN
142 tau = zero
143 RETURN
144 END IF
145
146 xnorm =
dznrm2( n-1, x, incx )
147 alphr = dble( alpha )
148 alphi = dimag( alpha )
149
150 IF( xnorm.EQ.zero ) THEN
151
152
153
154 IF( alphi.EQ.zero ) THEN
155 IF( alphr.GE.zero ) THEN
156
157
158
159 tau = zero
160 ELSE
161
162
163 tau = two
164 DO j = 1, n-1
165 x( 1 + (j-1)*incx ) = zero
166 END DO
167 alpha = -alpha
168 END IF
169 ELSE
170
171 xnorm =
dlapy2( alphr, alphi )
172 tau = dcmplx( one - alphr / xnorm, -alphi / xnorm )
173 DO j = 1, n-1
174 x( 1 + (j-1)*incx ) = zero
175 END DO
176 alpha = xnorm
177 END IF
178 ELSE
179
180
181
182 beta = sign(
dlapy3( alphr, alphi, xnorm ), alphr )
184 bignum = one / smlnum
185
186 knt = 0
187 IF( abs( beta ).LT.smlnum ) THEN
188
189
190
191 10 CONTINUE
192 knt = knt + 1
193 CALL zdscal( n-1, bignum, x, incx )
194 beta = beta*bignum
195 alphi = alphi*bignum
196 alphr = alphr*bignum
197 IF( (abs( beta ).LT.smlnum) .AND. (knt .LT. 20) )
198 $ GO TO 10
199
200
201
202 xnorm =
dznrm2( n-1, x, incx )
203 alpha = dcmplx( alphr, alphi )
204 beta = sign(
dlapy3( alphr, alphi, xnorm ), alphr )
205 END IF
206 savealpha = alpha
207 alpha = alpha + beta
208 IF( beta.LT.zero ) THEN
209 beta = -beta
210 tau = -alpha / beta
211 ELSE
212 alphr = alphi * (alphi/dble( alpha ))
213 alphr = alphr + xnorm * (xnorm/dble( alpha ))
214 tau = dcmplx( alphr/beta, -alphi/beta )
215 alpha = dcmplx( -alphr, alphi )
216 END IF
217 alpha =
zladiv( dcmplx( one ), alpha )
218
219 IF ( abs(tau).LE.smlnum ) THEN
220
221
222
223
224
225
226
227
228 alphr = dble( savealpha )
229 alphi = dimag( savealpha )
230 IF( alphi.EQ.zero ) THEN
231 IF( alphr.GE.zero ) THEN
232 tau = zero
233 ELSE
234 tau = two
235 DO j = 1, n-1
236 x( 1 + (j-1)*incx ) = zero
237 END DO
238 beta = dble( -savealpha )
239 END IF
240 ELSE
241 xnorm =
dlapy2( alphr, alphi )
242 tau = dcmplx( one - alphr / xnorm, -alphi / xnorm )
243 DO j = 1, n-1
244 x( 1 + (j-1)*incx ) = zero
245 END DO
246 beta = xnorm
247 END IF
248
249 ELSE
250
251
252
253 CALL zscal( n-1, alpha, x, incx )
254
255 END IF
256
257
258
259 DO 20 j = 1, knt
260 beta = beta*smlnum
261 20 CONTINUE
262 alpha = beta
263 END IF
264
265 RETURN
266
267
268
double precision function dlamch(CMACH)
DLAMCH
double precision function dlapy2(X, Y)
DLAPY2 returns sqrt(x2+y2).
double precision function dlapy3(X, Y, Z)
DLAPY3 returns sqrt(x2+y2+z2).
subroutine zdscal(N, DA, ZX, INCX)
ZDSCAL
subroutine zscal(N, ZA, ZX, INCX)
ZSCAL
complex *16 function zladiv(X, Y)
ZLADIV performs complex division in real arithmetic, avoiding unnecessary overflow.
real(wp) function dznrm2(n, x, incx)
DZNRM2