%% Linear and Circular Convolution
% This example shows how to establish an equivalence between linear and circular convolution.
% Linear and circular convolution are fundamentally different operations. However, there are conditions under which linear and circular convolution are equivalent. Establishing this equivalence has important implications. For two vectors, x and y, the circular convolution is equal to the inverse discrete Fourier transform (DFT) of the product of the vectors' DFTs. Knowing the conditions under which linear and circular convolution are equivalent allows you to use the DFT to efficiently compute linear convolutions.
% The linear convolution of an N-point vector, x, and an L-point vector, y, has length N + L - 1.
% For the circular convolution of x and y to be equivalent, you must pad the vectors with zeros to length at least N + L - 1 before you take the DFT. After you invert the product of the DFTs, retain only the first N + L - 1 elements.
% Create two vectors, x and y, and compute the linear convolution of the two vectors.

x = [2 1 2 1];
y = [1 2 3];
clin = conv(x,y);

%
% The output has length 4+3-1.
% Pad both vectors with zeros to length 4+3-1. Obtain the DFT of both vectors, multiply the DFTs, and obtain the inverse DFT of the product.

xpad = [x zeros(1,6-length(x))];
ypad = [y zeros(1,6-length(y))];
ccirc = ifft(fft(xpad).*fft(ypad));

%
% The circular convolution of the zero-padded vectors, xpad and ypad, is equivalent to the linear convolution of x and y. You retain all the elements of ccirc because the output has length 4+3-1.
% Plot the output of linear convolution and the inverse of the DFT product to show the equivalence.

subplot(2,1,1)
stem(clin,'filled')
ylim([0 11])
title('Linear Convolution of x and y')

subplot(2,1,2)
stem(ccirc,'filled')
ylim([0 11])
title('Circular Convolution of xpad and ypad')

%
% Pad the vectors to length 12 and obtain the circular convolution using the inverse DFT of the product of the DFTs. Retain only the first 4+3-1 elements to produce an equivalent result to linear convolution.

N = length(x)+length(y)-1;
xpad = [x zeros(1,12-length(x))];
ypad = [y zeros(1,12-length(y))];
ccirc = ifft(fft(xpad).*fft(ypad));
ccirc = ccirc(1:N);

%
% The Signal Processing Toolbox™ software has a function, cconv, that returns the circular convolution of two vectors. You can obtain the linear convolution of x and y using circular convolution with the following code.

ccirc2 = cconv(x,y,6);

% cconv internally uses the same DFT-based procedure illustrated in the previous example.
% Copyright 2012 The MathWorks, Inc.