@@ -135,24 +135,26 @@ function eigvals2x2(d1::Number, d2::Number, e::Number)
135
135
r2 = hypot (d1 - d2, 2 * e) / 2
136
136
return r1 + r2, r1 - r2
137
137
end
138
- function eigQL2x2 ! (d:: StridedVector , e:: StridedVector , j:: Integer , vectors:: Matrix )
138
+ function eig2x2 ! (d:: StridedVector , e:: StridedVector , j:: Integer , vectors:: Matrix )
139
139
dj = d[j]
140
- dj1 = d[j+ 1 ]
140
+ dj1 = d[j + 1 ]
141
141
ej = e[j]
142
142
r1 = (dj + dj1) / 2
143
143
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 ] = λ⁻
147
148
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)
153
155
else
154
- c = one (c )
155
- s = zero (c )
156
+ s = abs (ej) / hypot (ej, λ⁻ - dj )
157
+ c = copysign ( sqrt ( 1 - s * s), - ej )
156
158
end
157
159
158
160
_updateVectors! (c, s, j, vectors)
@@ -173,14 +175,16 @@ function eigvalsPWK!(S::SymTridiagonal{T}; tol = eps(T)) where {T<:Real}
173
175
end
174
176
while true
175
177
# 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]))
178
180
blockend = be - 1
179
181
break
180
182
end
181
183
blockend = n
182
184
end
183
185
186
+ @debug " submatrix" blockstart blockend
187
+
184
188
# Deflate?
185
189
if blockstart == blockend
186
190
@debug " Deflate? Yes!"
@@ -200,11 +204,12 @@ function eigvalsPWK!(S::SymTridiagonal{T}; tol = eps(T)) where {T<:Real}
200
204
μ = d[blockstart] - sqrte / (μ + copysign (r, μ))
201
205
202
206
# QL bulk chase
207
+ @debug " Values before PWK QL bulge chase" e[blockstart] e[blockend- 1 ] μ
203
208
singleShiftQLPWK! (S, μ, blockstart, blockend)
204
209
205
210
rotations = blockend - blockstart
206
211
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
208
213
end
209
214
if blockstart >= n
210
215
break
@@ -243,32 +248,37 @@ function eigQL!(
243
248
@inbounds begin
244
249
while true
245
250
# 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]))
248
253
blockend = be - 1
249
254
break
250
255
end
251
256
blockend = n
252
257
end
258
+
259
+ @debug " submatrix" blockstart blockend
260
+
253
261
# Deflate?
254
262
if blockstart == blockend
255
263
@debug " Deflate? Yes!"
256
264
blockstart += 1
257
265
elseif blockstart + 1 == blockend
258
266
@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
261
269
else
262
270
@debug " Deflate? No!"
263
271
# Calculate shift
264
- μ = (d[blockstart+ 1 ] - d[blockstart]) / (2 * e[blockstart])
272
+ μ = (d[blockstart + 1 ] - d[blockstart]) / (2 * e[blockstart])
265
273
r = hypot (μ, one (T))
266
274
μ = d[blockstart] - (e[blockstart] / (μ + copysign (r, μ)))
267
275
268
276
# QL bulk chase
277
+ @debug " Values before bulge chase" e[blockstart] e[blockend - 1 ] d[blockstart] μ
269
278
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]
271
280
end
281
+
272
282
if blockstart >= n
273
283
break
274
284
end
@@ -291,32 +301,35 @@ function eigQR!(
291
301
@inbounds begin
292
302
while true
293
303
# 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]))
296
306
blockend = be - 1
297
307
break
298
308
end
299
309
blockend = n
300
310
end
311
+
312
+ @debug " submatrix" blockstart blockend
313
+
301
314
# Deflate?
302
315
if blockstart == blockend
303
316
@debug " Deflate? Yes!"
304
317
blockstart += 1
305
318
elseif blockstart + 1 == blockend
306
319
@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
309
322
else
310
323
@debug " Deflate? No!"
311
324
# Calculate shift
312
- μ = (d[blockend- 1 ] - d[blockend]) / (2 * e[blockend- 1 ])
325
+ μ = (d[blockend - 1 ] - d[blockend]) / (2 * e[blockend - 1 ])
313
326
r = hypot (μ, one (T))
314
- μ = d[blockend] - (e[blockend- 1 ] / (μ + copysign (r, μ)))
327
+ μ = d[blockend] - (e[blockend - 1 ] / (μ + copysign (r, μ)))
315
328
316
329
# QR bulk chase
330
+ @debug " Values before QR bulge chase" e[blockstart] e[blockend - 1 ] d[blockend] μ
317
331
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]
320
333
end
321
334
if blockstart >= n
322
335
break
0 commit comments