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
Post a Comment