Jump to content

Recommended Posts

I am trying to create a code section that will take a 1D array and create a moving average array.  Sorry if this is a bad description.  I want to take x elements of the input array, average them, and put that average in the first element of a new array.  Then take the next x elements, average them, and put them as the second element of the new array.  I want this done until the array is empty.
 
I have two possible ways to do it, but neither are running as fast as I wanted them to.  I want to see if anyone knows of a faster way to conduct this averaging.

 

Thanks

Joe

post-41745-0-29380400-1404254943_thumb.j

post-41745-0-20619800-1404254944_thumb.j

Share this post


Link to post
Share on other sites

That's not quite a moving average, rather a down-sampling - i.e. Filtered Array is shorter than Input Data.  Your first solution is pretty good - just speed it up with a Parallel For Loop.  An alternative is to reshape into a 2D array.  Both these come out roughly the same speed, about 5x faster on my machine than your solutions above.

 

post-3889-0-82171900-1404257804.png

 

If you want a true Moving Average (where the result is the same length as the original) I think this suggestion from the NI forums using an FIR filter is nice and simple, although you might look carefully at the first Num values if that's important.

 

post-3889-0-43491200-1404258457.png

Edited by GregSands
  • Like 1

Share this post


Link to post
Share on other sites

You have to be careful with the FIR filter the way you're using it because it applies a shift to your data by the amount of "Num of Averages".

To fix that, you have to do some padding at both ends of your input data. In this example I just repeat the first and last value:

post-28303-0-67116300-1404288460_thumb.p

 

If you run it through a graph it becomes obvious:

post-28303-0-07739400-1404288605_thumb.p

  • Like 2

Share this post


Link to post
Share on other sites

Hadn't thought of using a FIR filter.  :thumbup1:  I bench marked a mean method and your FIR method. The FIR method was ~8-9x faster on my system than the mean with standard for loop, and the FIR was ~2-3x faster with the mean method for loop set for parallelism.

Share this post


Link to post
Share on other sites

I don't have LabVIEW installed on this machine and I may be confusing LabVIEW and MATLAB primatives, but I've seen a pretty fast approach that relies on a cumulative summation.  Textually, the algorithm is:

B=CumulativeSum(A)

SlidingAverage(i)=(B(i+windowsize)-B(i))/windowsize

Adjust indices as necessary to center your window in the right place and be careful with the edge conditions.

Share this post


Link to post
Share on other sites

Thanks for your help.  I was able to parallelize the for loop with the mean in it and it helped speed it up.  I didn't try the FIR approach.  I'm still waiting on verification that the averaging will work for the customer.

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.