Julia:如何计算包含 NaN 的向量的卷积?
Julia: How to compute convolution of vectors containing NaNs?
Julia 中的卷积函数具有以下行为:
_
_ _ _(_)_ | A fresh approach to technical computing
(_) | (_) (_) | Documentation: https://docs.julialang.org
_ _ _| |_ __ _ | Type "?help" for help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 0.6.1 (2017-10-24 22:15 UTC)
_/ |\__'_|_|_|\__'_| | Official http://julialang.org/ release
|__/ | x86_64-pc-linux-gnu
julia> conv([1,2,NaN],[1])
3-element Array{Float64,1}:
NaN
NaN
NaN
这是一个错误吗?或者这与conv
使用的FFT算法有关?
如果其中一个向量包含 NaN
,我如何在 Julia 中计算卷积(出于性能原因不能手动计算)?在这个例子中,结果应该是:
3-element Array{Float64,1}:
1.0
2.0
NaN
因为julia中的conv
函数使用了FFT。
你是什么意思"not manually"?用julia写自己的卷积函数应该还是很快的。
例如
function native_conv{T,V}(u::Array{T,1}, v::Array{V,1})
m = length(u)
n = length(v)
w = zeros(promote_type(T,V), m+n-1)
@inbounds begin
for j in 1:m, k in 1:n
w[j+k-1] += u[j]*v[k]
end;end
return w
end
或者这可能会更快(使用 FFT 进行转换,将 NaN 设置为零,然后重新归一化)。
编辑:v
(过滤器)较大时速度更快。
function nanconv{T}(u::Array{T,1},v)
nans = find(isnan, u)
u = copy(u)
u[nans] .= zero(T) # set nans2zero
pass1 = conv(u,v) # do convolution
u[u.>0] .= one(T) #
norm = conv(u,v) # get normalizations (also gets rid of edge effects)
u[:] .= one(T) #
norm .= norm./(conv(u,v)) # put edge effects back
w = pass1 ./ norm # normalize
reshaped_nans = reshape_nans(nans,length(v))
w[reshaped_nans] .= NaN # reset Nans
return w
end
function reshape_nans(nans,lv)
out = zeros(Int, length(nans)*lv)
j = 1;
inc = lv - 1
for i in nans
inds = i:(i+inc)
out[j:j+inc] = inds
j += inc + 1
end
out
end
Julia 中的卷积函数具有以下行为:
_
_ _ _(_)_ | A fresh approach to technical computing
(_) | (_) (_) | Documentation: https://docs.julialang.org
_ _ _| |_ __ _ | Type "?help" for help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 0.6.1 (2017-10-24 22:15 UTC)
_/ |\__'_|_|_|\__'_| | Official http://julialang.org/ release
|__/ | x86_64-pc-linux-gnu
julia> conv([1,2,NaN],[1])
3-element Array{Float64,1}:
NaN
NaN
NaN
这是一个错误吗?或者这与conv
使用的FFT算法有关?
如果其中一个向量包含 NaN
,我如何在 Julia 中计算卷积(出于性能原因不能手动计算)?在这个例子中,结果应该是:
3-element Array{Float64,1}:
1.0
2.0
NaN
因为julia中的conv
函数使用了FFT。
你是什么意思"not manually"?用julia写自己的卷积函数应该还是很快的。
例如
function native_conv{T,V}(u::Array{T,1}, v::Array{V,1})
m = length(u)
n = length(v)
w = zeros(promote_type(T,V), m+n-1)
@inbounds begin
for j in 1:m, k in 1:n
w[j+k-1] += u[j]*v[k]
end;end
return w
end
或者这可能会更快(使用 FFT 进行转换,将 NaN 设置为零,然后重新归一化)。
编辑:v
(过滤器)较大时速度更快。
function nanconv{T}(u::Array{T,1},v)
nans = find(isnan, u)
u = copy(u)
u[nans] .= zero(T) # set nans2zero
pass1 = conv(u,v) # do convolution
u[u.>0] .= one(T) #
norm = conv(u,v) # get normalizations (also gets rid of edge effects)
u[:] .= one(T) #
norm .= norm./(conv(u,v)) # put edge effects back
w = pass1 ./ norm # normalize
reshaped_nans = reshape_nans(nans,length(v))
w[reshaped_nans] .= NaN # reset Nans
return w
end
function reshape_nans(nans,lv)
out = zeros(Int, length(nans)*lv)
j = 1;
inc = lv - 1
for i in nans
inds = i:(i+inc)
out[j:j+inc] = inds
j += inc + 1
end
out
end