I tried to write my own circular convolution function in python using the fact that for two signals $f$ and $g$ we have
$$ \widehat{(f * g)} = f \cdot g $$
So I tried this
from scipy import array, zeros, signal
from scipy.fftpack import fft, ifft, convolve
def conv(f, g):
# transform f and g to frequency domain
F = fft(f)
G = fft(g)
# multiply entry-wise
C = F * G
# transfer C to time domain
c = ifft(C)
return c
However, for f = array([1,2,3,4])
and g = array([5,4,3,2])
I get
conv(f,g) = [ 34.+0.j 32.+0.j 34.+0.j 40.+0.j]
convolve.convolve(f,g) = [ 1.48219694e-322 2.07507571e-322 3.06320700e-322 3.26083326e-322]
signal.convolve(f,g,'same') = [14 26 40 29]
The first function is mine, the second one comes from the fft pack and the third one is from the scipy signal package. All return different results. How does this happen and what is the "correct" one?
The circular convolution I want is
$$(f*g)[n] = \sum_{p=0}^{N-1} f[p]g[n-p] $$ where $f[p] = f_{p \mod N}$. Can somebody help me?
Edit: I added a direct calculation for $(f*g)$
def direct(f,g):
r = zeros(len(f))
for k in range(len(f)):
for p in range(len(f)):
r[k] = r[k] + (f[p] * g[k-p])
return r
which returns the same result as my own implementation above. So my implementation seems correct. However, why do convolve.convolve
and signal.convolve
return other results?