In terms of understanding the convolution theorem i've created the following MatLab code: [ BEGIN CODE] function checkconvolutiontheorem [data Fs] = wavread('pop.wav'); % a 5 second sample of pop-music signal = data(1:453); % Signal consists of 453 non-zero elements. kernel = data(1:60); % Kernel consists of 60 non-zero elements. timesignal = conv(signal,kernel); % Convolution in spatial domain. plot(1:256, timesignal(1:256),'b'); hold on; h = zeros(1,512); h(1:453) = signal; signal = h; k = zeros(1,512); k(1:60) = kernel; kernel = k; fs = fft(signal,512); % Convert signal to frequencydomain. fk = fft(kernel,512); % Convert kernel to frequencydomain. % Use polar notation to calculate Re and Im of the pointwise product. ReY = real(fs(1,:)).*real(fk(1,:)) - imag(fs(1,:)).*imag(fk(1,:)); ImY = imag(fs(1,:)).*real(fk(1,:)) + real(fs(1,:)).*imag(fk(1,:)); convertedrealsignal = ifft(ReY,512); % Convert back to spatial domain convertedimagsignal = ifft(ImY,512); % Convert back to spatial domain. restructeredsignal = convertedrealsignal+abs(convertedimagsignal); plot(1:256, restructeredsignal(1:256), 'r'); hold off; end [END CODE] The signal and kernel are chosen so that they convolution fits into a 512 sample period. My problem is that the two plots arent identical. Can anyone correct my mistake? Thanks.
Visualising the convolution theorem.
Started by ●December 5, 2008
Reply by ●December 6, 20082008-12-06
On 5 Des, 23:04, Casper.Pt...@gmail.com wrote:> In terms of understanding the convolution theorem i've created the > following MatLab code: > > [ BEGIN CODE] > function checkconvolutiontheorem > > [data Fs] = wavread('pop.wav'); % a 5 second sample of pop-musicFirst, use random data or whatever, so others who don't have this wav file can check your code.> signal = data(1:453); % Signal consists of 453 non-zero elements. > kernel = data(1:60); �% Kernel consists of 60 non-zero elements. > > timesignal = conv(signal,kernel); � % Convolution in spatial domain. > plot(1:256, timesignal(1:256),'b'); > hold on; > > h = zeros(1,512); > h(1:453) = signal; > signal = h; > > k = zeros(1,512); > k(1:60) = kernel; > kernel = k; > > fs = fft(signal,512); % Convert signal to frequencydomain. > fk = fft(kernel,512); % Convert kernel to frequencydomain.The lines below are wrong:> % Use polar notation to calculate Re and Im of the pointwise product. > ReY = real(fs(1,:)).*real(fk(1,:)) - imag(fs(1,:)).*imag(fk(1,:)); > ImY = imag(fs(1,:)).*real(fk(1,:)) + real(fs(1,:)).*imag(fk(1,:)); > > convertedrealsignal = ifft(ReY,512); % Convert back to spatial domain > convertedimagsignal = ifft(ImY,512); % Convert back to spatial domain.Instead use Y = fs.*fk; restructuredsignal = real(ifft(Y));> % restructeredsignal = convertedrealsignal+abs(convertedimagsignal); > > plot(1:256, restructeredsignal(1:256), 'r'); > hold off; > end > [END CODE] > > The signal and kernel are chosen so that they convolution fits into a > 512 sample period. My problem is that the two plots arent identical. > Can anyone correct my mistake?Rune
Reply by ●December 6, 20082008-12-06
Casper, Rune correctly told you how to fix it and write it efficiently. However, he has identified a couple of lines as wrong that are not wrong, but how you used them later is wrong. Since you appear to understand (or be trying to understand) the operations in a particular manner, I have made minimal changes to fix your code to make it correct. Again, Rune's way is correct and more efficient, but I think it helps to understand where you went wrong. Note comments denoted by %DB. Dirk ========================== function checkconvolutiontheorem %DB Used data I could get other than 'pop.wav' %DB [data Fs] = wavread('pop.wav'); % a 5 second sample of pop-music data =randn(1,512); signal = data(1:453); % Signal consists of 453 non-zero elements. kernel = data(1:60); % Kernel consists of 60 non-zero elements. timesignal = conv(signal,kernel); % Convolution in spatial domain. plot(timesignal,'b'); %DB changed to plot whole thing, optional hold on; %DB h = zeros(1,512); %DB Removed, already set, optional %DB h(1:453) = signal; %DB signal = h; %DB k = zeros(1,512); %DB Removed, already set, optional %DB k(1:60) = kernel; %DB kernel = k; fs = fft(signal,512); % Convert signal to frequencydomain. fk = fft(kernel,512); % Convert kernel to frequencydomain. % Use polar notation to calculate Re and Im of the pointwise product. %DB "Polar"? Lines are okay. ReY = real(fs(1,:)).*real(fk(1,:)) - imag(fs(1,:)).*imag(fk(1,:)); ImY = imag(fs(1,:)).*real(fk(1,:)) + real(fs(1,:)).*imag(fk(1,:)); %DB Removed 3 lines, incorrect %DB "restructeredsignal" was probably meant to be "reconstructedsignal", %DB it's only a name, but it means something. %DB convertedrealsignal = ifft(ReY,512); % Convert back to spatial domain %DB convertedimagsignal = ifft(ImY,512); % Convert back to spatial domain. %DB restructeredsignal = convertedrealsignal+abs (convertedimagsignal); %DB Added, correct, !THIS IS WHAT YOU MISSED! restructeredsignal=ifft(ReY+j*ImY,512); plot(restructeredsignal, 'r'); %DB changed to plot whole thing, optional %DB Added to verify results, should be =0, optional error=timesignal-restructeredsignal; plot(error,'k') hold off; end
Reply by ●December 7, 20082008-12-07