help-octave
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Yet Another Vectorization Problem


From: Moo
Subject: Re: Yet Another Vectorization Problem
Date: Mon, 19 Jul 2010 18:20:09 +0200

The glaring issue I see is here:



 av=[]   Defining the running mean as a matrix.



You should always always always preallocate memory when you are "filling in" values for a vector/matrix/whatever.  Even if you do not know exactly how big the array will be, try to allocate extra, and then cut off the excess after you are done.  The way that Octave handles this:
 
 for i = 1:1:9001
   av(i,:) = [(sum(data(i:999+i,:),1))/1000];  %the data(i:999+i,:) bit is
doing what I described above
 end


would be, on every iteration, check if av has the space to store the next row i.  When it sees that it doesn't, it allocates memory for a completely new, slightly larger, array to accommodate the new input, copies over all the old data, deletes the old array, then stores the values for the new row.  This isn't so bad for small size arrays, but when you are doing it 9000 times it will slow down things a lot.

Aside from that, the trick with moving average is that you can look at moving average as, on each step, taking the old value, adding a new data element, and removing the oldest data element.  So try this instead:

av=zeros(9001,21);

av(1,:) = sum(data(1:1000,:),1)/1000;

for i=2:9001
av(i,:) = av(i-1) + (data(999+i,:) - data(i-1,:))/1000;   %subtract the old row and add the new row
end

Another option without for loops is using cumsum().  This is much less efficient on paper, but I'm not sure if it would end up being faster in practice, what with vector processing, etc:

av=zeros(9001,21);
av(1,:) = sum(data(1:1000,:),1)/1000;

temp = cumsum(data,1)/1000;
av(2:9001) = temp(1001:10000,:) - temp(1:9000,:);

reply via email to

[Prev in Thread] Current Thread [Next in Thread]