简体   繁体   English

为什么numpy.convolve不能表现出关联性?

[英]Why does numpy.convolve not behave associatively?

I know discrete convolutions are supposed to be associative. 我知道离散卷积应该是缔合的。 So if I have some array, x, then x * (x * (x * x)) should equal (x * x) * (x * x). 因此,如果我有某个数组x,则x *(x *(x * x))应该等于(x * x)*(x * x)。 But there are some situations where that doesn't happen. 但是在某些情况下不会发生这种情况。

Here is code that exercises that formula with four examples: 这是使用四个示例练习该公式的代码:

[1, 1]  # Works
[-54298238, 5998425]  # Works
[-95.3720828588315, 52.6296402253613]  # Works
[-94.25133703348938, 90.41999267567854]  # Broken
import numpy as np

def main():

    int_ok = np.array([1, 1], dtype=np.int)
    int_larger = np.array(
        [-54298238,5998425], dtype=np.int
    )

    float_ok = np.array(
        [-95.3720828588315, 52.6296402253613], dtype=np.float
    )
    float_broken = np.array(
        [-94.25133703348938, 90.41999267567854], dtype=np.float
    )

    fixtures = [int_ok, int_larger, float_ok, float_broken]

    for fixture in fixtures:
        reference = np.convolve(
            fixture,
            np.convolve(
                fixture,
                np.convolve(
                    fixture,
                    fixture
                )
            )
        )

        tmp = np.convolve(fixture, fixture)
        test = np.convolve(tmp, tmp)

        print('input', fixture)
        print('reference output', reference)
        print('output', test)
        all_equal = all(reference == test)
        print('all equal', all_equal)
        if not all_equal:
            print('error', np.abs(reference - test))


if __name__ == '__main__':
    main()

I assume this is due to some kind of numerical instability, but I can't quite figure out what's going on. 我认为这是由于某种数值不稳定引起的,但我无法完全弄清楚发生了什么。

Does anyone have any ideas? 有人有什么想法吗?

Thanks. 谢谢。

Inspired by this comment Why does numpy.convolve not behave associatively? 受到此评论的启发, 为什么numpy.convolve不能表现出关联性? by Mark Dickinson, I reworked my original code so that I'm no longer assuming the results are strictly the same, but rather using numpy.allclose. 由Mark Dickinson编写,我对原始代码进行了重新设计,以便不再假设结果完全相同,而是使用numpy.allclose。

Here is the modified code: 这是修改后的代码:

import numpy as np


def main():

    int_ok = np.array([1, 1], dtype=np.int)
    int_larger = np.array(
        [-54298238,5998425], dtype=np.int
    )

    float_ok = np.array(
        [-95.3720828588315, 52.6296402253613], dtype=np.float
    )
    float_broken = np.array(
        [-94.25133703348938, 90.41999267567854], dtype=np.float
    )

    fixtures = [int_ok, int_larger, float_ok, float_broken]

    for fixture in fixtures:
        reference = np.convolve(
            fixture,
            np.convolve(
                fixture,
                np.convolve(
                    fixture,
                    fixture
                )
            )
        )

        tmp = np.convolve(fixture, fixture)
        test = np.convolve(tmp, tmp)

        if np.allclose(reference, test):
            print('OK', fixture)
        else:
            print('FAIL', fixture)


if __name__ == '__main__':
    main()

numpy.allclose is returning True , so I think this is the best solution I'm going to get. numpy.allclose返回True ,所以我认为这是我要获得的最佳解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM