@@ -135,24 +135,26 @@ function eigvals2x2(d1::Number, d2::Number, e::Number)
135135 r2 = hypot (d1 - d2, 2 * e) / 2
136136 return r1 + r2, r1 - r2
137137end
138- function eigQL2x2 ! (d:: StridedVector , e:: StridedVector , j:: Integer , vectors:: Matrix )
138+ function eig2x2 ! (d:: StridedVector , e:: StridedVector , j:: Integer , vectors:: Matrix )
139139 dj = d[j]
140- dj1 = d[j+ 1 ]
140+ dj1 = d[j + 1 ]
141141 ej = e[j]
142142 r1 = (dj + dj1) / 2
143143 r2 = hypot (dj - dj1, 2 * ej) / 2
144- λ = r1 + r2
145- d[j] = λ
146- d[j+ 1 ] = r1 - r2
144+ λ⁺ = r1 + r2
145+ λ⁻ = r1 - r2
146+ d[j] = λ⁺
147+ d[j + 1 ] = λ⁻
147148 e[j] = 0
148- c = ej / (dj - λ)
149- if isfinite (c) # FixMe! is this the right fix for overflow?
150- h = hypot (one (c), c)
151- c /= h
152- s = inv (h)
149+ if iszero (ej)
150+ c = one (λ⁺)
151+ s = zero (λ⁺)
152+ elseif abs (λ⁺ - dj) > abs (λ⁻ - dj)
153+ c = - ej / hypot (ej, λ⁺ - dj)
154+ s = sqrt (1 - c* c)
153155 else
154- c = one (c )
155- s = zero (c )
156+ s = abs (ej) / hypot (ej, λ⁻ - dj )
157+ c = copysign ( sqrt ( 1 - s * s), - ej )
156158 end
157159
158160 _updateVectors! (c, s, j, vectors)
@@ -173,14 +175,16 @@ function eigvalsPWK!(S::SymTridiagonal{T}; tol = eps(T)) where {T<:Real}
173175 end
174176 while true
175177 # Check for zero off diagonal elements
176- for be = blockstart+ 1 : n
177- if abs (e[be- 1 ]) <= tol * sqrt (abs (d[be- 1 ])) * sqrt (abs (d[be]))
178+ for be = ( blockstart + 1 ) : n
179+ if abs (e[be - 1 ]) <= tol * sqrt (abs (d[be - 1 ])) * sqrt (abs (d[be]))
178180 blockend = be - 1
179181 break
180182 end
181183 blockend = n
182184 end
183185
186+ @debug " submatrix" blockstart blockend
187+
184188 # Deflate?
185189 if blockstart == blockend
186190 @debug " Deflate? Yes!"
@@ -200,11 +204,12 @@ function eigvalsPWK!(S::SymTridiagonal{T}; tol = eps(T)) where {T<:Real}
200204 μ = d[blockstart] - sqrte / (μ + copysign (r, μ))
201205
202206 # QL bulk chase
207+ @debug " Values before PWK QL bulge chase" e[blockstart] e[blockend- 1 ] μ
203208 singleShiftQLPWK! (S, μ, blockstart, blockend)
204209
205210 rotations = blockend - blockstart
206211 iter += rotations
207- @debug " QL, blockstart, blockend, e[blockstart], e[blockend-1], μ, rotations " blockstart blockend e[blockstart] e[blockend- 1 ] μ rotations
212+ @debug " Values after PWK QL bulge chase " e[blockstart] e[blockend- 1 ] rotations
208213 end
209214 if blockstart >= n
210215 break
@@ -243,32 +248,37 @@ function eigQL!(
243248 @inbounds begin
244249 while true
245250 # Check for zero off diagonal elements
246- for be = blockstart+ 1 : n
247- if abs (e[be- 1 ]) <= tol * sqrt (abs (d[be- 1 ])) * sqrt (abs (d[be]))
251+ for be = ( blockstart + 1 ) : n
252+ if abs (e[be - 1 ]) <= tol * sqrt (abs (d[be - 1 ])) * sqrt (abs (d[be]))
248253 blockend = be - 1
249254 break
250255 end
251256 blockend = n
252257 end
258+
259+ @debug " submatrix" blockstart blockend
260+
253261 # Deflate?
254262 if blockstart == blockend
255263 @debug " Deflate? Yes!"
256264 blockstart += 1
257265 elseif blockstart + 1 == blockend
258266 @debug " Deflate? Yes, but after solving 2x2 block"
259- eigQL2x2 ! (d, e, blockstart, vectors)
260- blockstart += 1
267+ eig2x2 ! (d, e, blockstart, vectors)
268+ blockstart += 2
261269 else
262270 @debug " Deflate? No!"
263271 # Calculate shift
264- μ = (d[blockstart+ 1 ] - d[blockstart]) / (2 * e[blockstart])
272+ μ = (d[blockstart + 1 ] - d[blockstart]) / (2 * e[blockstart])
265273 r = hypot (μ, one (T))
266274 μ = d[blockstart] - (e[blockstart] / (μ + copysign (r, μ)))
267275
268276 # QL bulk chase
277+ @debug " Values before bulge chase" e[blockstart] e[blockend - 1 ] d[blockstart] μ
269278 singleShiftQL! (S, μ, blockstart, blockend, vectors)
270- @debug " QL, blockstart, blockend, e[blockstart], e[blockend- 1] μ " blockstart blockend e [blockstart] e[blockend - 1 ] μ
279+ @debug " Values after bulge chase " e[blockstart] e[blockend - 1 ] d [blockstart]
271280 end
281+
272282 if blockstart >= n
273283 break
274284 end
@@ -291,32 +301,35 @@ function eigQR!(
291301 @inbounds begin
292302 while true
293303 # Check for zero off diagonal elements
294- for be = (blockstart+ 1 ): n
295- if abs (e[be- 1 ]) <= tol * sqrt (abs (d[be- 1 ])) * sqrt (abs (d[be]))
304+ for be = (blockstart + 1 ): n
305+ if abs (e[be - 1 ]) <= tol * sqrt (abs (d[be - 1 ])) * sqrt (abs (d[be]))
296306 blockend = be - 1
297307 break
298308 end
299309 blockend = n
300310 end
311+
312+ @debug " submatrix" blockstart blockend
313+
301314 # Deflate?
302315 if blockstart == blockend
303316 @debug " Deflate? Yes!"
304317 blockstart += 1
305318 elseif blockstart + 1 == blockend
306319 @debug " Deflate? Yes, but after solving 2x2 block!"
307- eigQL2x2 ! (d, e, blockstart, vectors)
308- blockstart += 1
320+ eig2x2 ! (d, e, blockstart, vectors)
321+ blockstart += 2
309322 else
310323 @debug " Deflate? No!"
311324 # Calculate shift
312- μ = (d[blockend- 1 ] - d[blockend]) / (2 * e[blockend- 1 ])
325+ μ = (d[blockend - 1 ] - d[blockend]) / (2 * e[blockend - 1 ])
313326 r = hypot (μ, one (T))
314- μ = d[blockend] - (e[blockend- 1 ] / (μ + copysign (r, μ)))
327+ μ = d[blockend] - (e[blockend - 1 ] / (μ + copysign (r, μ)))
315328
316329 # QR bulk chase
330+ @debug " Values before QR bulge chase" e[blockstart] e[blockend - 1 ] d[blockend] μ
317331 singleShiftQR! (S, μ, blockstart, blockend, vectors)
318-
319- @debug " QR, blockstart, blockend, e[blockstart], e[blockend-1], d[blockend], μ" blockstart blockend e[blockstart] e[blockend- 1 ] d[blockend] μ
332+ @debug " Values after QR bulge chase" e[blockstart] e[blockend - 1 ] d[blockend]
320333 end
321334 if blockstart >= n
322335 break
0 commit comments