The question is what kind of “handling of edges” do you want?
I need to see what choices I have. On another application I use, moving averages are not defined at the points that require non-existent datapoints. For example, for a 3-point boxcar filter, the first and last points are undefined in the result of the filter because the first point requires one datapoint to the left and the last point requires one datapoint to the right.
This is one sensible choice. There are other sensible choices.
But, conv
is highly unusual as a filter. A normal filter preserves the number of datapoints. For this reason, I don’t know which timestep each point in the output of conv
corresponds to. The original data is a timeseries [(t1, x1), (t2, x2), . . . , (tN, xN)] but the output has more points than N.
I wrote my code I posted above, by just guessing what conv
does.
I want to reduce the amplitude of ocean tides from my time series. Because my purpose is visualization (I plot graphs), the filter doesn’t have to be sophisticated at all. But the boxcar moving average has too much lobes in its frequency response. The Gaussian filter is perhaps ideal, but the Hann filter is close enough and it’s nice in that its width in the physical domain is finite.
Because I plot the data with time on the horizontal axis, I need to know which time each datapoint corresponds to.
Any way, I still need to figure out what conv
does. None of your descriptions actually shows the math.
I tried to see what exactly is a vector convolution. I haven’t found the formula. I looked at the source code of conv
but it calls another function, which calls another function, . . .
I google-searched. There is a nice Matlab webpage showing vector convolutions but it doesn’t show the math either. The writer of the page assumes that the reader knows what a vector convolution is.
Convolution between two 1-d functions in an infinite domain is well known, but for a finite domain, you need to make a choice.
conv
treats edges by assuming that your vectors are extended infinitely far with zeros on each side, and it only returns the parts of the theoretically infinitely long output vector that isn’t guaranteed to be zero thanks to that extension.
So, I’ll try to convert your words to math. Suppose we have a continuous signal x(t) which is defined only in [0,T]. You are saying that we extend x(t) as
x(t) = 0 for t > T or t < 0
Right? Then, the convolution is
y(t) = integral_{-∞}^{∞} w(t - t’) x(t’) dt’
= integral_{0}^{T} w(t - t’) x(t’) dt’
where w(t) is symmetric and compact support ( w(t) = 0 for |t| > K ).
Now, I see that y(t) extends at least to t = −K and t = T + K.
That’s why the result of conv
has tails on both sides and I can deduce the width of these extra datapoints.
Vectors are a bit harder to understand because the indices don’t extend to 0, -1, -2, . . . in the result of filtering.