Skip to main content

linear algebra - Discrete Convolution



Ask to compute the convolution of 2 lists, I managed to do so, with what I feel is rather heavy :


Let my 2 lists be :


a = {1,2,3,4} b = {1,1,1,1,1,1};


The below function adds 0s on each part of one list given the Length of the other


bpad[listA_, listB_] :=
Flatten@{
Table[0, {Length@listA - 1}],
listB,
Table[0, {Length@listA - 1}]
}


bpad[a,b]

Out = {0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0}


The following ones gives me the lists part I need to do the dot product with :


convParts[listA_, listB_] :=
Table[
Range[i, i + Length@listA - 1],
{i, Range[Length@bpad[listA, listB] - Length@listA + 1]}]


convParts[a, b]

Out= {{1, 2, 3, 4}, {2, 3, 4, 5}, {3, 4, 5, 6}, {4, 5, 6, 7}, {5, 6, 7,8}, {6, 7, 8, 9}, {7, 8, 9, 10}, {8, 9, 10, 11}, {9, 10, 11, 12}}


Finally the convolution itself :


convolve[listA_, listB_] :=
Total@(bpad[listA, listB][[#]]*Reverse@listA) & /@
convParts[listA, listB]

convolve[a,b]


Out= {1, 3, 6, 10, 10, 10, 9, 7,4}


How could I improve my solution, at each function or overall level.


Doing this for a class, it is, once again my opportunity to advertise for Mathematica against Matlab. I like in those case to show several solution



Answer



You could use ListConvolve:


ListConvolve[a, b, {1, -1}, 0]

concerning the padding:


ArrayPad[b, 3, 0]


And you could use Partition for the second of your steps:


Partition[Range[Length[ArrayPad[b, 3, 0]]], 3, 1]

Comments