朱莉娅:如何计算含有NaNs的载体的卷积?

时间:2018-01-24 10:59:10

标签: julia convolution

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 s,我如何在Julia中计算卷积(由于性能原因不能手动计算)?在此示例中,结果应为:

3-element Array{Float64,1}:
   1.0
   2.0
 NaN  

1 个答案:

答案 0 :(得分:7)

这是因为julia中的conv函数使用FFT。

你是什么意思“不是手动”?在julia中编写自己的卷积函数应该仍然很快。

e.g。

 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