Analytic convolution

define functions to use for convolution

impulseExp[t_,te_]:=Piecewise[{{Exp[-t/te],t≥0},{0,t<0}}];
impulseGauss[t_,tw_]:=Exp[-(t^2)/(tw^2)];
impulseRect[t_,t0_]:=UnitBox[t/t0];

the Convolve[ ] function performs the convolution analytically

check Mathematica help for arguments of the function.

convGaussRect[τ_,tw_,t0_]=Convolve[impulseGauss[t,tw],impulseRect[t,t0],t,τ]

test convolution with Gaussian and Rect

twTst=0.2;
t0Tst=3;
τRange=3;
GraphicsArray[{Plot[{impulseGauss[t,twTst],impulseRect[t,t0Tst]},{t,-τRange,τRange}],
Plot[convGaussRect[τ,twTst,t0Tst],{τ,-τRange,τRange}]}]

test convolution with exponential and rect
note Piecewise boundaries of integration

convExpRect[τ_,te_,t0_]=Convolve[impulseExp[t,te],impulseRect[t,t0],t,τ]

teTst=0.2;
t0Tst=3;
τRange=3;
GraphicsArray[{Plot[{impulseExp[t,teTst],impulseRect[t,t0Tst]},{t,-τRange,τRange}],Plot[convExpRect[τ,twTst,t0Tst],{τ,-τRange,τRange},PlotPoints->100]}]

by running this Manipulate[ ] demo, you can see how the convolution integral is the overlap of the two functions as the delay is varied

Manipulate[
Plot[{impulseExp[τ-t,teTst],impulseRect[t,t0Tst],impulseExp[τ-t,teTst]impulseRect[t,t0Tst]},{t,-τRange,τRange},Filling->Bottom],{τ,-τRange,τRange}]

Numerical calculations with ListConvolve

When working with numerical data or functions that have been sampled, we use ListConvolve[ ]

set up kernels

grid for convolution kernel

α=0.15;
nptsKernel=40;
kernelLst=Range[nptsKernel];

exponential impulse response

impulseExp[t_]:=Exp[-α (nptsKernel-t)];
impulseExpLst=impulseExp[kernelLst];
ListPlot[impulseExpLst,Joined->True,PlotRange->All]

gaussian impulse response

impulseGauss[t_]:=Exp[-(α^2)((((nptsKernel/2)-t))^2)];
impulseGaussLst=impulseGauss[kernelLst];
ListPlot[impulseGaussLst,Joined->True]

rectangular impulse response

rect[t_,w_]:=(1-UnitStep[(t/w)-(1/2)])UnitStep[(t/w)+(1/2)];
impulseRectLst=rect[kernelLst-nptsKernel/2,3/α];
ListPlot[impulseRectLst,Joined->True]

input functions

nptsGrid=400;
gridLst=Range[nptsGrid];

sets of delta functions

try varying the delay between the delta functions to see what happens

gLstDelta2=0 Range[nptsGrid];
delta=20;
gLstDelta2[[(nptsGrid/2)]]=1;
gLstDelta2[[(nptsGrid/2)+delta]]=1;
ListPlot[gLstDelta2,Joined->True,PlotRange->{0,1}]

gLstDelta3=0 Range[nptsGrid];
gLstDelta3[[(nptsGrid/2)]]=1;
gLstDelta3[[(nptsGrid/2)+delta]]=1;
gLstDelta3[[(nptsGrid/2)+2delta]]=1;
ListPlot[gLstDelta3,Joined->True,PlotRange->{0,1}]

gLstDelta4=0 Range[nptsGrid];
gLstDelta4[[(nptsGrid/2)]]=1;
gLstDelta4[[(nptsGrid/2)+delta]]=1;
gLstDelta4[[(nptsGrid/2)+2delta]]=1;
gLstDelta4[[(nptsGrid/2)+3delta]]=1;

ListPlot[gLstDelta4,Joined->True,PlotRange->{0,1}]

rectangular input square pulse (add zeroes to either side)

rectWid=60;
gLstRect=rect[gridLst-nptsGrid/2,rectWid];
ListPlot[gLstRect,Joined->True,PlotRange->{0,1}]

convolutions

ListConvolve notes:
kernel (shorter list) is the first argument

exponential with rect

note that the array is shorter by the length of the kernel

hLst=ListConvolve[impulseExpLst,gLstRect];
Length[hLst]
ListPlot[hLst,Joined->True,PlotRange->All]

putting ,1 as the last argument pads out to restore the original length, but result is shifted by nptsKernel/2
, -1 pads on left side

hLst=ListConvolve[impulseExpLst,gLstRect,1];
Length[hLst]
ListPlot[hLst,Joined->True,PlotRange->All]

the last argument indicates padding with 0 instead of a cyclic convolution
the second-to-last is used to make sure the list is the same length as before, and that the result isn’t shifted by the operation

hLst=ListConvolve[impulseGaussLst,gLstRect,{nptsKernel/2,-nptsKernel/2-1},0];
Length[hLst]
ListPlot[{hLst,gLstRect},Joined->True,PlotRange->{{140,260},All}]

correlation doesn't flip the kernel first

hLst=ListCorrelate[impulseExpLst,gLstRect];
ListPlot[hLst,Joined->True,PlotRange->All]

double delta with exponential

hLst=ListConvolve[impulseExpLst,gLstDelta2,1];
ListPlot[hLst,Joined->True,PlotRange->All]

hLst=ListCorrelate[impulseExpLst,gLstDelta2];
ListPlot[hLst,Joined->True,PlotRange->All]

with gaussian

hLst=ListConvolve[impulseGaussLst,gLstDelta2,1];
ListPlot[hLst,Joined->True,PlotRange->All]

rectangular impulse response with 2 delta functions input

hLst=ListConvolve[impulseRectLst,gLstDelta2];
ListPlot[hLst,Joined->True,PlotRange->All]

rectangular impulse response with 3 delta functions input

hLst=ListConvolve[impulseRectLst,gLstDelta3];
ListPlot[hLst,Joined->True,PlotRange->All]

rectangular impulse response with 4 delta functions input

hLst=ListConvolve[impulseRectLst,gLstDelta4];
ListPlot[hLst,Joined->True,PlotRange->All]

rectangular impulse response with rectangular input

hLst=ListConvolve[impulseRectLst,gLstRect];
ListPlot[hLst,Joined->True,PlotRange->All]