不可名状的 bug 的发现过程 "今日平安无事"
先说我要干嘛:想学一学 performance-tips
里面的姿势。需要初始化一个复数数组,能初始化为 0 最好。
v0.6.4 的文档是这样教的
我是这样做的:
arr_S = Array{Complex128}(3,3) * 0
Wz = Array{Complex128}(41,41) * 0
WNM = Vector{Complex128}(630) * 0
输出看了下 3x3 的矩阵,效果拔群,就没看后面的。
然后我就拿这个数组存结果,有的是直接赋值,有的是再上面初始化为 0 的基础上累加。
然后累加就炸了。
我想把放结果的矩阵每个元素都缩放到 [0, 1],就先取模再求最大值
colors = abs.(Wz)
facecolors=get_cmap("jet").o(colors/maximum(colors))
最后画图一看结果怎么都是一个颜色,不对。然后打印了最大值发现是 NaN
,就坑了。
我自己试了下 0.6.4/0.7/1.0 都是
julia> maximum([0, NaN, 1])
NaN
查来查去发现这个初始化就有问题,三个数组中按一定概率出 NaN
简单地说:用类似 Array{Complex128}(3,3)
生成的数组里可能有 NaN
从而导致一些意料之外的错误。
复现代码。
NaN_bug_test.jl @0.6.4/0.7
function bug_test!(bug_number, i)
res3x = any(isnan, Array{Complex128}(3,3))
res41x = any(isnan, Array{Complex128}(41,41))
res41x0 = any(isnan, Array{Complex128}(41,41) * 0)
res41x0im = any(isnan, Array{Complex128}(41,41) * 0im)
if (res3x | res41x | res41x0 | res41x0im)
bug_number += 1
print("i=",i," anyNaN? 3x3: ", res3x, " 41x41: ", res41x,
" 41x41x0: ", res41x0, " 41x41x0im: ", res41x0im, "\n")
end
end
function bug_test_loop()
bug_number = 0
for i in 0:1_000
bug_test!(bug_number, i)
end
return bug_number
end
function main()
bug_number = bug_test_loop()
if bug_number == 0
print("今日平安无事\n")
else
print("今天又出了 ", bug_number, " 个 bug\n")
end
end
main()
PS: 上面用
arr .* 0
效果是一样的
VSC@0.6.4 命令行逐行运行结果:
i=86 anyNaN? 3x3: false 41x41: false 41x41x0: false 41x41x0im: true
i=88 anyNaN? 3x3: false 41x41: false 41x41x0: false 41x41x0im: true
i=90 anyNaN? 3x3: false 41x41: true 41x41x0: false 41x41x0im: false
i=258 anyNaN? 3x3: false 41x41: true 41x41x0: true 41x41x0im: false
i=260 anyNaN? 3x3: false 41x41: true 41x41x0: false 41x41x0im: false
i=261 anyNaN? 3x3: false 41x41: false 41x41x0: true 41x41x0im: false
i=442 anyNaN? 3x3: false 41x41: false 41x41x0: false 41x41x0im: true
i=443 anyNaN? 3x3: false 41x41: true 41x41x0: false 41x41x0im: false
i=446 anyNaN? 3x3: false 41x41: true 41x41x0: true 41x41x0im: false
i=606 anyNaN? 3x3: false 41x41: false 41x41x0: false 41x41x0im: true
i=771 anyNaN? 3x3: false 41x41: true 41x41x0: false 41x41x0im: false
今天又出了 11 个 bug
i=0 anyNaN? 3x3: false 41x41: true 41x41x0: false 41x41x0im: false
i=93 anyNaN? 3x3: false 41x41: false 41x41x0: true 41x41x0im: false
今天又出了 2 个 bug
i=649 anyNaN? 3x3: false 41x41: false 41x41x0: false 41x41x0im: true
i=804 anyNaN? 3x3: false 41x41: true 41x41x0: false 41x41x0im: false
i=987 anyNaN? 3x3: false 41x41: true 41x41x0: false 41x41x0im: false
今天又出了 3 个 bug
i=59 anyNaN? 3x3: false 41x41: true 41x41x0: false 41x41x0im: false
今天又出了 1 个 bug
今日平安无事
今日平安无事
目前的解决办法
用 fill(0im, 41,41)
for i in 1_000_000
resFill41x = any(isnan, fill(0im, 41,41))
if resFill41x
print("i=",i," anyNaN? 41x41: ", resFill41x, "\n")
end
end
当然是没有输出啦。
不知道还有没有其它的姿势。
1.0 里用 any(isnan, Array{ComplexF64}(undef, 41, 41))
或 any(isnan, Array{ComplexF64}(undef, 41, 41)*0)
还是会有以上的问题,不知道 undef
是干嘛用的