【问题标题】:Differences between Python and Julia convolutions?Python 和 Julia 卷积之间的区别?
【发布时间】:2018-09-26 08:09:08
【问题描述】:

我正在尝试将一段代码从 Python 转换为 Julia,但我很难理解以下卷积之间的输出差异:

Python:

conc = [10,100,1000,5,2000,200,20]
conc_filter = [1,2,3]
sp.ndimage.convolve1d(conc, conc_filter,axis=0,mode='constant')

输出:[ 120, 1230, 2305, 5010, 4215, 6420, 640]

朱莉娅:

conc = [10,100,1000,5,2000,200,20]
conc_filter = [1,2,3]
conv(conc,conc_filter)

输出:[10, 120, 1230, 2305, 5010, 4215, 6420, 640, 60]

谁能解释为什么输出长度不同?为了重新创建 Python 输出,我尝试提出一个逻辑公式,将输入/过滤器大小与切片 conv 输出并获得相同结果所需的索引范围相关联。然而,我的运气并不好。是否有可以产生相同输出的 Julia 函数?

【问题讨论】:

  • 你使用的是什么版本的 Julia,conv 函数是从哪里来的?
  • 在您的 Julia 代码中,输入数组有 7 个元素,但输出有 9 个元素。对吗?
  • @StevenSiew 在版本 1.0.0 中运行 OP 的 Julia 代码,我得到了相同的 9 个元素。 (此外,由于 DSP 包已从“基本”语言中删除,因此 OP 可能正在运行 1.0 之前的版本。)OTOH,OP 可能没有在他的问题代码中包含 add DSP 和 using DSP 命令。
  • 它们都是正确的,它们只是以不同的方式处理边界条件。
  • @DNF 您似乎可以写出您的 cmets 作为答案。您可能已经解决了 OP 的问题。

标签: python julia convolution


【解决方案1】:

您使用的是什么 Python conv 例程?这是 Python 的 numpy convolve:

>>> conc = [10,100,1000,5,2000,200,20]
>>> conc_filter = [1,2,3]

>>> numpy.convolve(conc, conc_filter,axis=0,mode='constant')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: convolve() got an unexpected keyword argument 'axis'

>>> numpy.convolve(conc, conc_filter)
array([  10,  120, 1230, 2305, 5010, 4215, 6420,  640,   60])

您可能需要查看 Python 包的文档,并了解如何使 fft() 类型例程满足您的需要。

【讨论】:

  • 我想坚持使用长度保留版本,因为它适用于我正在处理的模型的其余部分。我希望我可以进行相反的转换 - 即更改 Julia 代码,使其复制 ndimage.convolve1d 输出。
  • 如果您总是使用 3 元素的第二个向量进行卷积,您可能只需要使用 array[2: end-1] 来删除第一个和最后一个元素。
  • 不幸的是,上面的 3 元素过滤器只是一个示例。我正在尝试提出适用于所有输入和过滤器长度的方法。
【解决方案2】:

对于那些感兴趣的人,我制定了在“常量”模式下使用的填充方案,作为参数传递给 Python 卷积函数。找到输入/输出大小之间关系的困难在于对称和非对称卷积滤波器的左右填充方式。

下面的 Julia 代码似乎与所有测试输入/输出的 Python 等效代码相匹配。

conc = [10,100,1000,5,2000,200,20]
conc_filter = [1,2,3]

n=length(conc)
m=length(conc_filter)

padleft=ceil(Int32,m/2)-1
padright=floor(Int32,m/2)

conc =append!(zeros(padleft),conc)
conc = append!(conc,zeros(padright))

out = zeros(n)
for i in 1:n
    for j in 1:m
        out[i] += conc[i+j-1]*conc_filter[m-j+1]
    end
end
out

结果: [120、1230、2305、5010、4215、6420、640]

【讨论】:

    【解决方案3】:

    假设我正确理解您的问题:

    根据stackexchange上this的回答,Julia示例的向量长度是正确的。

    N + M - 1 给出的输出向量长度为​​ 9,如 Julia 答案所示。

    您确定 Python 代码和/或复制的输出正确吗?

    【讨论】:

    • 正确的向量长度是一个定义问题。通常,您会得到N+M-1,但通常希望保留原始向量的长度。在这种情况下,您可以指定边界条件,例如常量(例如零填充)、周期性、反射等。如果您使用周期性边界条件,则可以使用 FFT 实现卷积,这在许多情况下非常有效案例。
    • @DNF 那么你知道 Julia 中是否存在保长卷积?我没有任何运气谷歌搜索/搜索 Julia 文档。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 2011-12-17
    • 1970-01-01
    • 2017-11-14
    • 2019-05-06
    • 2021-06-10
    相关资源
    最近更新 更多