TIANLUN ZHU
TIANLUN ZHU

Reputation: 351

How to check convolution theorem in MATLAB? My result is wrong

I am trying to check convolution theorem in MATLAB. I have a signal called sine_big_T. Then I have a filter called W. W and sine_big_T have the same length.

The convolution theorem says that fft(sine_big_T.*W) should be same as the convolution of fft(sine_big_T) with fft(W).

I am quite confused about this theorem. fft(sine_big_T.*W) will give me a array with length length(sine_big_T). However, conv(fft(sine_big_T), fft(W)) gives me a array with length length(sine_big_T) + length(W) - 2. I have tried the commend conv(fft(sine_big_T), fft(W), 'same'), but the result is still much different from fft(sine_big_T.*W).

T = 128;
big_T = 8*T;
small_T = T/8;
sine_big_T = zeros(1,129);
sine_small_T = zeros(1,129);
W = zeros(1,129);
for i = 0:T
    sine_big_T(1, i+1) = sin(2*pi/big_T*i);
    W(1, i + 1) = 1 - cos(2*pi/T * i);
end


figure
plot(1:129,fft(sine_big_T.*W));

I_fft = fft(sine_big_T);
W_fft = fft(W);
test = conv(I_fft, W_fft,'same');
figure
plot(1:length(I_fft), test)

From the theorem, the two plots should look same. But the result is not even close. I think the way I use conv is not correct. What is the right way to verify the theorem?

Upvotes: 0

Views: 335

Answers (1)

Cris Luengo
Cris Luengo

Reputation: 60780

Using conv with 'same' is correct. You are seeing two things:

  1. fft defines the origin in the first array element, not the middle of the domain. This does not play well with conv. Use this instead:

    test = ifftshift( conv( fftshift(I_fft), fftshift(W_fft), 'same' ) );
    

    The fftshift function shifts the origin to the middle of the array, where it is good for conv with 'same', and ifftshift shifts the origin back to the first element.

  2. Normalization. The FFT is typically normalized so that multiplication in the frequency domain is convolution in the spatial domain. Since you are computing convolution in the frequency domain, the normalization is off. To correct the normalization, plot

    plot(1:129,fft(sine_big_T.*W)*length(W));
    

Upvotes: 3

Related Questions