Efficient way to calculate backwards average

Dear all,
I'm looking for an efficient way to calculate a backwards moving average, i.e., giving a vector A I want to calculate a vector A2 for which the element i is equal to mean(A(i:end)).
For the moment I am doing it this way:
A=rand(1,1000);
n=length(A);
A2=zeros(1,n)
for i=1:n
A2(i)=mean(A(i:end));
end
Is there any better way?
Thanks
Lorenzo

 Réponse acceptée

John D'Errico
John D'Errico le 29 Sep 2014
Modifié(e) : John D'Errico le 29 Sep 2014
First of all, what you SAY you are doing makes no sense. A is a 1000x1000 matrix, but A2 only a vector. And you have two i for loops, with only one end. And regardless of what size A is, n=size(A) will produce a vector. So 1:n will yield a problem in the for loop.
The code you show will fail in so many ways I won't bother to count. You should provide working code so someone can know what it is you really want!
Assuming that you really wanted to write this where A is a row vector...
Think about what cumsum does. Then, suppose you flipped the data before calling cumsum.
n = length(A);
A2 = fliplr(cumsum(fliplr(A))./(1:n)));
Of course, this is really not a true moving average, since that would involve a moving window of fixed length. But it is what you asked for.

4 commentaires

Image Analyst
Image Analyst le 29 Sep 2014
I don't know what he really wants , but according to what he said , he doesn't want a moving average. His window is not constant length, but gets shorter as the index approaches the end of the array. So I think your cumsum method might just do what he asked for, assuming A is a vector like he said but not like what his code made.
Lorenzo
Lorenzo le 30 Sep 2014
John, you are right, sorry about that. I edited the code in a text editor and then I forgot to update it here. It should be fixed now.
Lorenzo
Lorenzo le 30 Sep 2014
Modifié(e) : Lorenzo le 30 Sep 2014
John, works great, thanks. In case I have a matrix of signals instead of a single vector and I wanted to do what we are doing here with every column of this matrix, I can either loop trough the column and use you code above or do this:
c2=size(A);
rows=c2(1);
columns=c2(2);
A2=flipud(cumsum(flipud(A))./repmat((1:rows)',1,columns));
do you see any better way?
Thanks
Lorenzo
That will work fine, although a minor optimization would be to use bsxfun to do the divide instead of replicating the vector using repmat.
A2=flipud(bsxfun(@rdivide,cumsum(flipud(A)),(1:rows)'));

Connectez-vous pour commenter.

Plus de réponses (4)

José-Luis
José-Luis le 29 Sep 2014
numRows = 100;
numCols = 100;
data = rand(numRows,numCols);
result = flipud(bsxfun(@rdivide,cumsum(flipud(data)),(1:numRows)));

1 commentaire

Lorenzo
Lorenzo le 30 Sep 2014
Thanks José. I'm getting something weird at the end of the signal though… In case of a vector it should be:
result(end)=data(end)
but I'm not getting this with your method…

Connectez-vous pour commenter.

Chad Greene
Chad Greene le 29 Sep 2014

0 votes

This is a very fast moving average calculator. It centers data, so if you use an N-point moving average, after calculating the moving averaged, you could shift by N/2 to get the "backwards" moving average.

1 commentaire

Image Analyst
Image Analyst le 29 Sep 2014
He doesn't want a moving average. His window is not constant length, but gets shorter as the index approaches the end of the array.

Connectez-vous pour commenter.

SK
SK le 29 Sep 2014
Modifié(e) : SK le 29 Sep 2014
s = sum(A);
n = length(A);
A2 = (s - cumsum(A))/n;
is a little more elegant and I would think faster. But you have to add s/N to the beginning of A2 and remove the 0 at the end of A2.
The last operation (removing the zero) is misleadingly innocent:
A2(end) = [];
But you may soon get to know the consequences of it.

1 commentaire

Lorenzo
Lorenzo le 30 Sep 2014
Thanks SK. This doesn't seem to do what I need though… not sure what it is supposed to do…

Connectez-vous pour commenter.

Lorenzo
Lorenzo le 30 Sep 2014
Modifié(e) : Lorenzo le 30 Sep 2014

0 votes

Thanks everybody for the answers.
With a vector of 50k elements I get the following run time:
my method: 10.17 s
John's method: 0.006 s

1 commentaire

Stephen23
Stephen23 le 30 Sep 2014
Unless you are actually answering your own question, write a comment to your original question or one of the answers. There is no guarantee that the answers remain in any particular order...

Connectez-vous pour commenter.

Catégories

Community Treasure Hunt

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

Start Hunting!

Translated by