Fundamentals
Housekeeping
close all force; clear; clc; s = tf('s');
Convolution is a key mathematical concept both in dynamics and signal analysis, but it's rarely explained from an intuitive perspective. It's easy to look up the definition as
but what does this MEAN?
Before we answer that question, I would like to start with a familiar concept, the moving average. Consider the below signal, its moving average, and the convolution of the original signal with the "kernal" for a moving average.
n = 50;
kernal = ones(1,n);
signal = [zeros(1,200) ones(1,200) 2*ones(1,200) 0.5*ones(1,200) zeros(1,100)];
moving_average = movmean(signal, n);
convolution = (1/n)*conv(signal, kernal, 'same'); % the 1/n term is necessary to approximate a continous convolution
f = figure(); f.Position = [0,0,1800,500];
subplot(1,3,1)
stairs(signal);
title('original signal');
xlim([0, length(signal)]); ylim([min(signal), 1.2*max(signal)]);
subplot(1,3,2)
stairs(moving_average);
title('moving average');
xlim([0, length(signal)]); ylim([min(signal), 1.2*max(signal)]);
subplot(1,3,3)
stairs(convolution);
title('kernal convolution');
xlim([0, length(signal)]); ylim([min(signal), 1.2*max(signal)]);
Purely from observation it appears that the moving average, and the convolution of the signal with the moving average kernal are precisely the same thing (although slightly shifted in time)! In fact, convolution can be considered a generalizaton of the moving average!
This, I have found, is the most intuitive way of understanding what a convolution is really doing. In convoling two signals, we simply consider one of them to be a kernal and compute the generalized "moving average". The convolution in this understanding is essentially a "weighted moving average" of two signals.
To drive the point home, let us consider a more general example using the above signal convolved with a ramp function.
t = 1:1:length(signal);
l = 200;
ramp = [zeros(1,l) (2/l)*t(1,1:(l)) zeros(1,l)];
convolution2 = (1/l).*conv(signal, ramp, 'same'); % the 1/l term is necessary to approximate a continous convolution
f = figure(); f.Position = [0,0,1800,500];
subplot(1,3,1)
stairs(signal);
title('original signal');
xlim([0, length(signal)]); ylim([min(signal), 1.2*max(signal)]);
subplot(1,3,2)
stairs(ramp)
title('ramp signal');
xlim([0, length(signal)]); ylim([min(signal), 1.2*max(signal)]);
subplot(1,3,3)
stairs(convolution2);
title('kernal convolution');
xlim([0, length(signal)]); ylim([min(signal), 1.2*max(signal)]);