42 views (last 30 days)

Show older comments

Hi, I am new to matlab. I was solving a problem where I have to find moving average of a sample single .The output should be centered. I wrote the following code

t=linspace(-pi,pi,100);

rng default

x=sin(t) +0.25*rand(size(t));

window_s=5;

output_l=length(t) -window_s+1;

y=zeros(1,output_l);

for k=1:output_l

y(k)=(x(k) +x(k+1) + x(k+2)+x(k+3)+x(k+4))/5;

end

plot(t,x)

hold on

plot(t(1:output_l),y)

legend('Input Data', 'Filtered Data')

I dont know what is the meaning of centered moving average? Can someone tell me how can make the out put centered?

John D'Errico
on 3 Apr 2018

Edited: John D'Errico
on 3 Apr 2018

A rose by any other name would smell as sweet...

So, given the sequence

X = [1 2 6 4 3 7];

and a 3 point moving average, what do we get?

I'll put NaNs where we don't have sufficient information to give valid results. Later on, I'll show you how to use conv to produce essentially the same set of averages. But for now, I'll write out the computations in detail, so you can see what happened.

Trailing moving average. Here we use the current value at any point, and the previous two values. I'll write it out in detail, so you see what happens.

Xtrail = [NaN, NaN, mean([1 2 6]), mean([2 6 4]), mean([6 4 3]), mean([4 3 7])]

Xtrail =

NaN NaN 3 4 4.3333 4.6667

So as you see, the trailing moving average lacks sufficient information to have valid results for the first two averages, so I got two less averages. Or, perhaps you might decide to use a shorter average for the first two elements. That would be your choice of course. So we might use this:

Xtrail = [1, mean([1 2]), mean([1 2 6]), mean([2 6 4]), mean([6 4 3]), mean([4 3 7])]

Xtrail =

1 1.5 3 4 4.3333 4.6667

Leading moving average. No surprise, this has identical results. Except that the final two values lack sufficient information, unless we shorten the span of the moving average for the last two.

Xlead = [mean([1 2 6]), mean([2 6 4]), mean([6 4 3]), mean([4 3 7]), NaN , NaN]

Xlead =

3 4 4.3333 4.6667 NaN NaN

So, if we patch the final elements, we get this:

Xlead = [mean([1 2 6]), mean([2 6 4]), mean([6 4 3]), mean([4 3 7]), mean([3 7]), 7]

Xlead =

3 4 4.3333 4.6667 5 7

Centered moving average. Somehow, I think you figured this one out by now.

Xcenter = [NaN, mean([1 2 6]), mean([2 6 4]), mean([6 4 3]), mean([4 3 7]), NaN]

Xcenter =

NaN 3 4 4.3333 4.6667 NaN

So the very same numbers. All that matters is how you deal with the ends in any case.

Note that I could have written code using conv to do the same.

conv(X,ones(1,3)/3,'valid')

ans =

3 4 4.3333 4.6667

You can freely choose whether the means produced by conv are leading, trailing, or centered averages.

Remember that numbers are just numbers. Until you assign an interpretation, they are nothing more than a list of numbers.

Image Analyst
on 3 Apr 2018

It looks like it's the same as a moving average. The output pixel is the same location as the center of the window. If you didn't have an odd number of pixels in your window (but had an even number instead) then the center of the image would be a half pixel shifted, and would not be centered, but that's normally not something you would want to do. Since you have 5 elements, you're centered. You can skip the for loop and use conv(). Instead of:

for k=1:output_l

y(k)=(x(k) +x(k+1) + x(k+2)+x(k+3)+x(k+4))/5;

end

use conv():

y = conv(x, ones(1, 5)/5, 'valid');

Andrei Bobrov
on 3 Apr 2018

Edited: Andrei Bobrov
on 3 Apr 2018

variant for your case

n = 5;

x = randi(8,1,10);

y = movmean(x,n);

y = y((n-1)/2+1:end-(n-1)/2);

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!