Использование теоремы о свертке и БПФ не приводит к тому же результату, что и функция scipy.convolve - PullRequest
1 голос
/ 07 октября 2019

Я хочу познакомиться со свертками на основе Фурье. Поэтому я создал небольшой пример, используя numpy.fft и scipy.signal.convolve. Однако результаты двух операций разные, и я не знаю почему. У кого-нибудь есть идея?

Я уже пробовал использовать разные режимы scipy.signal.convolve.

Пример:

import numpy as np
from scipy.signal import convolve

# Generate example data
data = np.array([1, 1, 1, 1, 1, 1])
kernel = np.array([0, 1, 2, 1, 0, 0])

# Using scipy.signal.convolve
A = convolve(kernel, data, mode='full')
B = convolve(kernel, data, mode='valid')
C = convolve(kernel, data, mode='same')

# Using the convolution theorem 
D = np.fft.ifft(np.fft.fft(kernel) * np.fft.fft(data))

Результаты:

A = array([0, 1, 3, 4, 4, 4, 4, 3, 1, 0, 0])
B = array([4])
C = array([3, 4, 4, 4, 4, 3])

D = array([4.+0.j, 4.+0.j, 4.+0.j, 4.+0.j, 4.+0.j, 4.+0.j])

1 Ответ

2 голосов
/ 07 октября 2019

Вам нужно дополнить data и kernel нулями N-1, чтобы избежать круговой свертки ...

import numpy as np
from scipy.signal import convolve

# Generate example data
data = np.array([1, 1, 1, 1, 1, 1])
kernel = np.array([0, 1, 2, 1, 0, 0])

# Using scipy.signal.convolve
A = convolve(kernel, data, mode='full')

# Using the convolution theorem - need to pad with N-1 zeroes
data = np.array([1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0])
kernel = np.array([0, 1, 2, 1, 0, 0, 0, 0, 0, 0, 0])

D = np.fft.ifft(np.fft.fft(kernel) * np.fft.fft(data))

print (A)
print (D)

Результат:

[0 1 3 4 4 4 4 3 1 0 0]
[2.4e-16+0.j 1.0e+00+0.j 3.0e+00+0.j 4.0e+00+0.j 4.0e+00+0.j 4.0e+00+0.j
 4.0e+00+0.j 3.0e+00+0.j 1.0e+00+0.j 3.2e-16+0.j 1.6e-16+0.j]
...