这个节目
program bug
implicit none
double precision :: H1(4, 4), H2(4, 4), wr1(4), wi1(4), wr2(4), wi2(4), Z, work(10), dble, epsilon
integer*8 :: info
H1(:,:) = 0
H1(2, 1) = dble(z'bfdf916d32df0e1d')
H1(3, 2) = dble(z'bf782807624514d9')
H1(4, 3) = dble(z'bf80d94d89578784')
H1(1, 2) = dble(z'3fdf916d32df0e1d')
H1(2, 3) = dble(z'3f782807624514da')
H1(3, 4) = dble(z'3f80d94d89578784')
H2(:,:) = H1
H2(4,4) = epsilon(H2(4,4))
call dhseqr('E', 'N', 4_8, 1_8, 4_8, H1, 4_8, wr1, wi1, Z, 1_8, work, 10, info)
call dhseqr('E', 'N', 4_8, 1_8, 4_8, H2, 4_8, wr2, wi2, Z, 1_8, work, 10, info)
write(*,*) 'wr1: ', wr1
write(*,*) 'wi1: ', wi1
write(*,*) 'wr2: ', wr2
write(*,*) 'wi2: ', wi2
end program bug
产生
wr1: 0.0000000000000000 0.0000000000000000 0.0000000000000000 0.0000000000000000
wi1: 0.73992959728054897 -0.73992959728054897 8.2263841908860064E-003 -8.2263841908860064E-003
wr2: 0.0000000000000000 0.0000000000000000 1.1102230246251565E-016 1.1102230246251565E-016
wi2: 0.49328639818703252 -0.49328639818703252 8.2263841908860116E-003 -8.2263841908860116E-003
在我装有 LAPACK 3.8 的机器上。
我不认为这里应该有条件问题。 我想收敛标准可能会被零对角线混淆。
我已经破解了这个错误。 我不确定,但看起来它是由 dlanv2 中的下溢/舍入错误引起的。
在迭代过程中会发生以下情况:
对于前 2 个特征值,我们最终得到以下子块:
0.0000E+00 4.9329E-01
-4.9329E-01 -9.8813-324
DLANV2 把它变成:
0.0000E+00 7.3993E-01
-7.3993E-01 0.0000E+00
原因是 DLANV2 的第 218 行出现舍入错误,CS 是 sqrt(0.5),所以 SN 也应该是 sqrt(0.5),而是变成了 -1。 甚至不是有效的旋转,更不用说正确规范化 2x2 块的旋转了。
事实上,对角线上的一个微小的非零值似乎完全破坏了计算
julia> eigvals([0.0 1.0; -1.0 0.0])
2-element Array{Complex{Float64},1}:
0.0 - 1.0im
0.0 + 1.0im
julia> eigvals([0.0 1.0; -1.0 nextfloat(0.0)])
2-element Array{Complex{Float64},1}:
0.0 - 0.5000000000000001im
0.0 + 0.5000000000000001im
julia> eigvals([0.0 1.0; -1.0 1e-310])
2-element Array{Complex{Float64},1}:
0.0 - 1.000000000000023im
0.0 + 1.000000000000023im