I have recently put together an array stacking (accumulate and divide) tool for 4096 element arrays. Here I can average an arbitrary number of arrays, 100+ in my case.
This is shown below:
My question to the community is, can anyone recommend a method for converting this approach to one with a rolling stack average (i.e. one array in while the oldest array out) instead of simply accumulating then average?
I understand that shift registers can achieve this, but due to the high number of arrays to be stacked, I'm ideally looking for a more versatile and, easily, scalable solution.
I have attached a simplified version of my stacking tool for clarity.
Thank you in advance.
You have attached a subVI that has no resemblance with your attached images
If this is a action engine subVI to calculate the average of the last N rows, you should not initialize the shift register.
All you need is a shift register with a 4096 x 100 2D array where you replace the oldest row with the new one. Average the columns as needed for the output.
Can you attach a VI that has more reasonable defaults in all controls?
Here's a quick demo how you can average the last N values of a 1D array (works with any history length or array size)
Just a quick draft. Check for bugs!
Note that this is efficient because it also keeps the running sum where it subtracts the oldest and adds the newest data. Much less math that always averaging all columns. (See my old presentation for details)
Thanks for your response.
What you mention sounds ideal. I am not sure what the most elegant way of doing this would be, however, is this what you had in mind:
As for vi, I posted a stripped-back version. Had a second go at that, so hopefully, the attached a better representation. In this example: the red plot is the stacked average of the input arrays (blue plot). Currently, the red plot updates every "stack index" interval. What I am trying to do is update every time a new array is received for the same "stack index" size (one in, one out).
...just saw your second response (you beat me to my reply!). What you show and describe sounds interesting. I'll have a deeper dive and let you know how I get on.
I said 2D array, not 100D array! So basically you want to create a 100 dimensional array where each dimension is 4096????
All memory from all computers in the world would not be able to even store a tiny fraction of 8x4096^100! (Even the number of atoms in the known universe is tiny compared to that number!)
I would like to stack average 100 arrays of 4096 elements, so 4096x100 into an averaged 4096x1 array, then roll this average one array at a time. I have the first part (that's in the example shown), but the rolling part I haven't found a way to scale this solution so far.
I am going to work through your solution just now. Thanks again for that.
You can take your 2D array and autoindex it on a FOR loop. Inside the FOR loop, place my VI. Take the output and autoindex at an output tunnel to get the "averaged" array of same size out. Each row will have the average of the 100 previous rows (except for the first 100 rows, where we have fewer, of course).
If this is not clear to you, I would recommend starting again with the tutorials listed at the top of the forum.
I have reviewed your VIs and just to check I am understanding you correctly, does your suggestion of nesting this inside a For loop create one averaged array out for every 100 raw (unaveraged) rows in or for every new row in (after the first 100 rows in)?