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). 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.
