104
105
106
107
108
109
110 INTEGER INCX, N
111 COMPLEX ALPHA, TAU
112
113
114 COMPLEX X( * )
115
116
117
118
119
120 REAL TWO, ONE, ZERO
121 parameter( two = 2.0e+0, one = 1.0e+0, zero = 0.0e+0 )
122
123
124 INTEGER J, KNT
125 REAL ALPHI, ALPHR, BETA, BIGNUM, SMLNUM, XNORM
126 COMPLEX SAVEALPHA
127
128
129 REAL SCNRM2, SLAMCH, SLAPY3, SLAPY2
130 COMPLEX CLADIV
132
133
134 INTRINSIC abs, aimag, cmplx, real, sign
135
136
138
139
140
141 IF( n.LE.0 ) THEN
142 tau = zero
143 RETURN
144 END IF
145
146 xnorm =
scnrm2( n-1, x, incx )
147 alphr = real( alpha )
148 alphi = aimag( 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 =
slapy2( alphr, alphi )
172 tau = cmplx( 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(
slapy3( 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 csscal( 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 =
scnrm2( n-1, x, incx )
203 alpha = cmplx( alphr, alphi )
204 beta = sign(
slapy3( 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/real( alpha ))
213 alphr = alphr + xnorm * (xnorm/real( alpha ))
214 tau = cmplx( alphr/beta, -alphi/beta )
215 alpha = cmplx( -alphr, alphi )
216 END IF
217 alpha =
cladiv( cmplx( one ), alpha )
218
219 IF ( abs(tau).LE.smlnum ) THEN
220
221
222
223
224
225
226
227
228 alphr = real( savealpha )
229 alphi = aimag( 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 = real( -savealpha )
239 END IF
240 ELSE
241 xnorm =
slapy2( alphr, alphi )
242 tau = cmplx( 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 cscal( 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
real function slapy2(X, Y)
SLAPY2 returns sqrt(x2+y2).
real function slapy3(X, Y, Z)
SLAPY3 returns sqrt(x2+y2+z2).
subroutine csscal(N, SA, CX, INCX)
CSSCAL
subroutine cscal(N, CA, CX, INCX)
CSCAL
complex function cladiv(X, Y)
CLADIV performs complex division in real arithmetic, avoiding unnecessary overflow.
real(wp) function scnrm2(n, x, incx)
SCNRM2
real function slamch(CMACH)
SLAMCH