Search code examples
matlabmatlab-figuresmoothing

Matlab filter vs smoothdata


I don't find a reason why the filter function seems to output something different than the smoothdata function. They both should implement a windowSize of 5 smoothing using a moving average. Can someone versed in these functions explain what's happening?

Here's the >link< to the documentation, code below adapted from there, added smoothdata (and for additional puzzle, the smooth function, that is also not the same):

% from documentation
t = linspace(-pi,pi,100);
rng default  %initialize random number generator
x = sin(t) + 0.25*rand(size(t));
windowSize = 5;
b = (1/windowSize)*ones(1,windowSize);
a = 1;
y = filter(b,a,x);

%this is added for this example, you need >Matlab 2017a to run this
y2=smoothdata(x,'movmean',windowSize)
%y3=smooth(x,100);  %bug in the code (obsolete)
y3=smooth(x,windowSize);

%now plot data
figure;
plot(t,x)
hold on
plot(t,y)
plot(t,y2)
plot(t,y3)
legend('Input Data','Filtered Data','smoothdata','smooth')

%show obvious parts of plot
xlim([0 3]);
ylim([0 1.25]);

Here's what I get as output:

WTF

Here's some inconsistency in the first part of the plot:

%this is added for this example, you need >Matlab 2017a to run this
y2 = smoothdata(x,'movmean',[windowSize-1,0]);
y3 =  smoothdata(padarray(x,[0 2]),'movmean',[windowSize-1,0]);
%now plot data
figure(1); clf;
plot(t,x)
hold on
plot(t(1:10),y(1:10))
plot(t(1:10),y2(1:10))
plot(t(1:10),y3(1:10))

legend('Input Data','Filtered Data','smoothdata',['padded ' char(10) 'smoothdata'])

%show obvious parts of plot
xlim([-3.1784   -2.3858]);

WTF2


Solution

  • The window parameter for smoothdata, if scalar, yields a window centered around the origin. filter implements a causal filter, meaning that it takes the mean of windowSize previous samples. Thus, the difference between these two results is a shift of windowSize/2 samples. You can see this shift clearly in your plot. Use two parameters to simulate the result of filter:

    y2 = smoothdata(x,'movmean',[windowSize-1,0])
    

    The smooth function also implements a moving average, the second parameter is the window size. You are using 100 here, instead of windowSize, which has a value of 5. Thus, this result is the average over 20 times as many values. Replicate the result using the right window size:

    y3 = smooth(x,windowSize);
    

    I presume y3 will be shifted w.r.t. the filter result, just like y2 was in the question.