<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Re: Efficient moving average algorithm in Discussions</title>
    <link>https://community.jmp.com/t5/Discussions/Efficient-moving-average-algorithm/m-p/29180#M19324</link>
    <description>That's a great solution. Note that any missing values in the data column ("current" in this example) will create blank values in the calculated data column from the row where the first missing data occurs to all rows below. It is a small issue to be aware of.</description>
    <pubDate>Tue, 15 Nov 2016 17:25:36 GMT</pubDate>
    <dc:creator>tmenzer0</dc:creator>
    <dc:date>2016-11-15T17:25:36Z</dc:date>
    <item>
      <title>Efficient moving average algorithm</title>
      <link>https://community.jmp.com/t5/Discussions/Efficient-moving-average-algorithm/m-p/8553#M8547</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Hello,&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Thanks to those who have posted on here before, I've found some useful answers!&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I have several large data sets (20 million points each!) from an oscilloscope. I want to calculate a moving average. However, the algorithm I've devised is very slow. Here is the code for my formula:&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;"&lt;/P&gt;&lt;P&gt;If(Row() &amp;lt; 100, Empty(), Summation(i = Row() - 99, Row(), :Current[i,Empty()]) / 100)&lt;/P&gt;&lt;P&gt;"&lt;/P&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="6272_Screen Shot 2014-05-09 at 1.40.00 PM.png" style="width: 359px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/364i3B6818EA2790B576/image-size/medium?v=v2&amp;amp;px=400" role="button" title="6272_Screen Shot 2014-05-09 at 1.40.00 PM.png" alt="6272_Screen Shot 2014-05-09 at 1.40.00 PM.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;As the width of the averaging window (in this case 100 samples) gets larger (say 500, 1000, or even 50000 or more), the calculation time becomes unreasonable. Does someone have a faster way of doing a moving average?&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Thanks!&lt;/P&gt;&lt;P&gt;Dane&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Tue, 18 Oct 2016 20:41:39 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Efficient-moving-average-algorithm/m-p/8553#M8547</guid>
      <dc:creator>daneo</dc:creator>
      <dc:date>2016-10-18T20:41:39Z</dc:date>
    </item>
    <item>
      <title>Re: Efficient moving average algorithm</title>
      <link>https://community.jmp.com/t5/Discussions/Efficient-moving-average-algorithm/m-p/8554#M8548</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;I can offer a couple of strategies here.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;I think both are more efficient that the Summation() operator you're currently using. I can't say they are the most efficient possible though.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;1) Use the Sum() function on a matrix.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;PRE __jive_macro_name="quote" class="jive_text_macro jive_macro_quote"&gt;&lt;BR /&gt;&lt;P style="font-size: 15px; font-family: Courier;"&gt;&lt;SPAN style="color: #032ce4;"&gt;If&lt;/SPAN&gt;&lt;STRONG&gt;(&lt;/STRONG&gt;&lt;SPAN style="color: #032ce4;"&gt;Row&lt;/SPAN&gt;&lt;STRONG&gt;()&lt;/STRONG&gt;&lt;SPAN style="color: #011993;"&gt;&amp;lt;&lt;/SPAN&gt;&lt;SPAN style="color: #011993;"&gt;:&lt;/SPAN&gt;Moving Avg Window&lt;SPAN style="color: #011993;"&gt;,&lt;/SPAN&gt;&lt;/P&gt;&lt;BR /&gt;&lt;P style="font-size: 15px; font-family: Courier;"&gt;&amp;nbsp; &lt;SPAN style="color: #009193;"&gt;&lt;STRONG&gt;.&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #011993;"&gt;,&lt;/SPAN&gt;&lt;/P&gt;&lt;BR /&gt;&lt;P style="font-size: 15px; font-family: Courier;"&gt;&amp;nbsp; &lt;SPAN style="color: #032ce4;"&gt;Sum&lt;/SPAN&gt;&lt;STRONG&gt;(&lt;/STRONG&gt; &lt;SPAN style="color: #011993;"&gt;:&lt;/SPAN&gt;Current&lt;STRONG&gt;[&lt;/STRONG&gt;&lt;SPAN style="color: #032ce4;"&gt;Index&lt;/SPAN&gt;&lt;STRONG&gt;(&lt;/STRONG&gt; &lt;SPAN style="color: #032ce4;"&gt;Row&lt;/SPAN&gt;&lt;STRONG&gt;()&lt;/STRONG&gt; &lt;SPAN style="color: #011993;"&gt;-&lt;/SPAN&gt; &lt;STRONG&gt;(&lt;/STRONG&gt;&lt;SPAN style="color: #011993;"&gt;:&lt;/SPAN&gt;Moving Avg Window &lt;SPAN style="color: #011993;"&gt;-&lt;/SPAN&gt; &lt;SPAN style="color: #009193;"&gt;&lt;STRONG&gt;1&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;STRONG&gt;)&lt;/STRONG&gt;&lt;SPAN style="color: #011993;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="color: #032ce4;"&gt;Row&lt;/SPAN&gt;&lt;STRONG&gt;()&lt;/STRONG&gt; &lt;STRONG&gt;)]&lt;/STRONG&gt; &lt;STRONG&gt;)&lt;/STRONG&gt; &lt;SPAN style="color: #011993;"&gt;/&lt;/SPAN&gt; &lt;SPAN style="color: #011993;"&gt;:&lt;/SPAN&gt;Moving Avg Window&lt;/P&gt;&lt;BR /&gt;&lt;P style="font-size: 15px; font-family: Courier;"&gt;&lt;STRONG&gt;)&lt;/STRONG&gt;&lt;/P&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/PRE&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="6275_JMPScreenSnapz003.png" style="width: 648px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/365iE127BD1BE18F9AC4/image-size/medium?v=v2&amp;amp;px=400" role="button" title="6275_JMPScreenSnapz003.png" alt="6275_JMPScreenSnapz003.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;This takes advantage of the speed of the matrix operation. The subscript of the &lt;EM&gt;Current&lt;/EM&gt; column in this formula is a matrix of the row numbers from the start of the moving average window to the current row number. My subscripting the column this way JMP returns a matrix and the Sum function is relatively efficient over a matrix.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;An even faster way though is to calculate this moving average over two columns. The first column simply maintains a moving sum by adding the value of &lt;EM&gt;Current &lt;/EM&gt;in one row to the value of the rolling sum in the previous row and then subtracting the value of Current from the row at the beginning of the window.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;Here's the formula for Moving Sum.&lt;/P&gt;&lt;PRE __jive_macro_name="quote" class="jive_text_macro jive_macro_quote"&gt;&lt;BR /&gt;&lt;P style="font-size: 15px; font-family: Courier;"&gt;&lt;SPAN style="color: #032ce4;"&gt;If&lt;/SPAN&gt;&lt;STRONG&gt;(&lt;/STRONG&gt;&lt;SPAN style="color: #032ce4;"&gt;Row&lt;/SPAN&gt;&lt;STRONG&gt;()&lt;/STRONG&gt;&lt;SPAN style="color: #011993;"&gt;&amp;lt;=&lt;/SPAN&gt;&lt;SPAN style="color: #011993;"&gt;:&lt;/SPAN&gt;Moving Avg Window&lt;SPAN style="color: #011993;"&gt;,&lt;/SPAN&gt;&lt;/P&gt;&lt;BR /&gt;&lt;P style="font-size: 15px; font-family: Courier;"&gt;&amp;nbsp; &lt;SPAN style="color: #032ce4;"&gt;If&lt;/SPAN&gt;&lt;STRONG&gt;(&lt;/STRONG&gt; &lt;SPAN style="color: #032ce4;"&gt;Row&lt;/SPAN&gt;&lt;STRONG&gt;()&lt;/STRONG&gt; &lt;SPAN style="color: #011993;"&gt;==&lt;/SPAN&gt; &lt;SPAN style="color: #009193;"&gt;&lt;STRONG&gt;1&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;SPAN style="color: #011993;"&gt;,&lt;/SPAN&gt;&lt;/P&gt;&lt;BR /&gt;&lt;P style="font-size: 15px; font-family: Courier;"&gt;&amp;nbsp; &lt;SPAN style="color: #011993;"&gt;:&lt;/SPAN&gt;Current&lt;SPAN style="color: #011993;"&gt;,&lt;/SPAN&gt;&lt;/P&gt;&lt;BR /&gt;&lt;P style="font-size: 15px; font-family: Courier;"&gt;&amp;nbsp; &lt;SPAN style="color: #032ce4;"&gt;Lag&lt;/SPAN&gt;&lt;STRONG&gt;(&lt;/STRONG&gt; &lt;SPAN style="color: #011993;"&gt;:&lt;/SPAN&gt;&lt;SPAN style="color: #032ce4;"&gt;Name&lt;/SPAN&gt;&lt;STRONG&gt;(&lt;/STRONG&gt; &lt;SPAN style="color: #942193;"&gt;"moving sum(x)"&lt;/SPAN&gt; &lt;STRONG&gt;)&lt;/STRONG&gt;&lt;SPAN style="color: #011993;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="color: #009193;"&gt;&lt;STRONG&gt;1&lt;/STRONG&gt;&lt;/SPAN&gt; &lt;STRONG&gt;)&lt;/STRONG&gt; &lt;SPAN style="color: #011993;"&gt;+&lt;/SPAN&gt; &lt;SPAN style="color: #011993;"&gt;:&lt;/SPAN&gt;Current&lt;/P&gt;&lt;BR /&gt;&lt;P style="font-size: 15px; font-family: Courier;"&gt;&amp;nbsp; &lt;STRONG&gt;)&lt;/STRONG&gt;&lt;SPAN style="color: #011993;"&gt;,&lt;/SPAN&gt;&lt;/P&gt;&lt;BR /&gt;&lt;P style="font-size: 15px; font-family: Courier;"&gt;&amp;nbsp; &lt;STRONG&gt;(&lt;/STRONG&gt;&lt;SPAN style="color: #032ce4;"&gt;Lag&lt;/SPAN&gt;&lt;STRONG&gt;(&lt;/STRONG&gt; &lt;SPAN style="color: #011993;"&gt;:&lt;/SPAN&gt;&lt;SPAN style="color: #032ce4;"&gt;Name&lt;/SPAN&gt;&lt;STRONG&gt;(&lt;/STRONG&gt; &lt;SPAN style="color: #942193;"&gt;"moving sum(x)"&lt;/SPAN&gt; &lt;STRONG&gt;)&lt;/STRONG&gt;&lt;SPAN style="color: #011993;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="color: #009193;"&gt;&lt;STRONG&gt;1&lt;/STRONG&gt;&lt;/SPAN&gt; &lt;STRONG&gt;)&lt;/STRONG&gt; &lt;SPAN style="color: #011993;"&gt;+&lt;/SPAN&gt; &lt;SPAN style="color: #011993;"&gt;:&lt;/SPAN&gt;Current&lt;STRONG&gt;)&lt;/STRONG&gt; &lt;SPAN style="color: #011993;"&gt;-&lt;/SPAN&gt;&lt;/P&gt;&lt;BR /&gt;&lt;P style="font-size: 15px; font-family: Courier;"&gt;&amp;nbsp; &lt;SPAN style="color: #032ce4;"&gt;Lag&lt;/SPAN&gt;&lt;STRONG&gt;(&lt;/STRONG&gt; &lt;SPAN style="color: #011993;"&gt;:&lt;/SPAN&gt;Current&lt;SPAN style="color: #011993;"&gt;,&lt;/SPAN&gt; &lt;SPAN style="color: #011993;"&gt;:&lt;/SPAN&gt;Moving Avg Window &lt;STRONG&gt;)&lt;/STRONG&gt;&lt;/P&gt;&lt;BR /&gt;&lt;P style="font-size: 15px; font-family: Courier;"&gt;&lt;STRONG&gt;)&lt;/STRONG&gt;&lt;/P&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/PRE&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="6276_JMPScreenSnapz004.png" style="width: 637px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/366iC0F519A37AF16FAD/image-size/medium?v=v2&amp;amp;px=400" role="button" title="6276_JMPScreenSnapz004.png" alt="6276_JMPScreenSnapz004.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;Then it's easy to have a column that divides &lt;EM&gt;Moving Sum&lt;/EM&gt; by the &lt;EM&gt;Moving Avg Window&lt;/EM&gt;.&lt;/P&gt;&lt;PRE __jive_macro_name="quote" class="jive_text_macro jive_macro_quote"&gt;&lt;BR /&gt;&lt;P style="font-size: 15px; font-family: Courier;"&gt;&lt;SPAN style="color: #032ce4;"&gt;If&lt;/SPAN&gt;&lt;STRONG&gt;(&lt;/STRONG&gt;&lt;SPAN style="color: #032ce4;"&gt;Row&lt;/SPAN&gt;&lt;STRONG&gt;()&lt;/STRONG&gt;&lt;SPAN style="color: #011993;"&gt;&amp;gt;=&lt;/SPAN&gt;&lt;SPAN style="color: #011993;"&gt;:&lt;/SPAN&gt;Moving Avg Window&lt;SPAN style="color: #011993;"&gt;,&lt;/SPAN&gt;&lt;/P&gt;&lt;BR /&gt;&lt;P style="font-size: 15px; font-family: Courier;"&gt;&amp;nbsp; &lt;SPAN style="color: #011993;"&gt;:&lt;/SPAN&gt;&lt;SPAN style="color: #032ce4;"&gt;Name&lt;/SPAN&gt;&lt;STRONG&gt;(&lt;/STRONG&gt; &lt;SPAN style="color: #942193;"&gt;"moving sum(x)"&lt;/SPAN&gt; &lt;STRONG&gt;)&lt;/STRONG&gt; &lt;SPAN style="color: #011993;"&gt;/&lt;/SPAN&gt; &lt;SPAN style="color: #011993;"&gt;:&lt;/SPAN&gt;Moving Avg Window&lt;SPAN style="color: #011993;"&gt;,&lt;/SPAN&gt;&lt;/P&gt;&lt;BR /&gt;&lt;P style="font-size: 15px; font-family: Courier;"&gt;&amp;nbsp; &lt;SPAN style="color: #009193;"&gt;&lt;STRONG&gt;.&lt;/STRONG&gt;&lt;/SPAN&gt;&lt;/P&gt;&lt;BR /&gt;&lt;P style="font-size: 15px; font-family: Courier;"&gt;&lt;STRONG&gt;)&lt;/STRONG&gt;&lt;/P&gt;&lt;BR /&gt;&lt;BR /&gt;&lt;/PRE&gt;&lt;P&gt;&lt;span class="lia-inline-image-display-wrapper lia-image-align-inline" image-alt="6277_JMPScreenSnapz005.png" style="width: 421px;"&gt;&lt;img src="https://community.jmp.com/t5/image/serverpage/image-id/367i7D5E26CCF483D384/image-size/medium?v=v2&amp;amp;px=400" role="button" title="6277_JMPScreenSnapz005.png" alt="6277_JMPScreenSnapz005.png" /&gt;&lt;/span&gt;&lt;/P&gt;&lt;P&gt;I'm attaching a data table that shows both of these methods. In the data table the &lt;EM&gt;Moving Avg Window&lt;/EM&gt; is a &lt;A href="http://www.jmp.com/support/help/Edit_Data_Tables.shtml#227066" rel="noopener noreferrer" target="_blank"&gt;Data Table Variable&lt;/A&gt;.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;To see the efficiency of the second method in this data table you may want to &lt;A href="http://www.jmp.com/support/help/Assign_Column_Properties.shtml#461857" rel="noopener noreferrer" target="_blank"&gt;suppress the evaluation&lt;/A&gt; of the of the &lt;EM&gt;Moving Avg(x)&lt;/EM&gt; column first.&lt;/P&gt;&lt;P&gt;&lt;/P&gt;&lt;P&gt;-Jeff&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Tue, 18 Oct 2016 20:41:59 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Efficient-moving-average-algorithm/m-p/8554#M8548</guid>
      <dc:creator>Jeff_Perkinson</dc:creator>
      <dc:date>2016-10-18T20:41:59Z</dc:date>
    </item>
    <item>
      <title>Re: Efficient moving average algorithm</title>
      <link>https://community.jmp.com/t5/Discussions/Efficient-moving-average-algorithm/m-p/8555#M8549</link>
      <description>&lt;HTML&gt;&lt;HEAD&gt;&lt;/HEAD&gt;&lt;BODY&gt;&lt;P&gt;Thanks, Jeff. These run much faster than the summation method!&lt;/P&gt;&lt;/BODY&gt;&lt;/HTML&gt;</description>
      <pubDate>Tue, 13 May 2014 22:38:57 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Efficient-moving-average-algorithm/m-p/8555#M8549</guid>
      <dc:creator>daneo</dc:creator>
      <dc:date>2014-05-13T22:38:57Z</dc:date>
    </item>
    <item>
      <title>Re: Efficient moving average algorithm</title>
      <link>https://community.jmp.com/t5/Discussions/Efficient-moving-average-algorithm/m-p/29180#M19324</link>
      <description>That's a great solution. Note that any missing values in the data column ("current" in this example) will create blank values in the calculated data column from the row where the first missing data occurs to all rows below. It is a small issue to be aware of.</description>
      <pubDate>Tue, 15 Nov 2016 17:25:36 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Efficient-moving-average-algorithm/m-p/29180#M19324</guid>
      <dc:creator>tmenzer0</dc:creator>
      <dc:date>2016-11-15T17:25:36Z</dc:date>
    </item>
    <item>
      <title>Re: Efficient moving average algorithm</title>
      <link>https://community.jmp.com/t5/Discussions/Efficient-moving-average-algorithm/m-p/29206#M19327</link>
      <description>&lt;P&gt;I usually find that if I can avoid the table all together it's faster. &amp;nbsp;This runs faster on my machine. &amp;nbsp;You'll notice that My numbers are different than Jeffs too. &amp;nbsp;That's simply because I mirror the numbers on the end then go x points out from the center (rather than last x points). &amp;nbsp;Also this has weighting of missing values so if you have any missing values it's a non issue. &amp;nbsp;At least I think so. &amp;nbsp;If you don't need a column at the end it's even faster too. &amp;nbsp;And the since it's just basically a concatted index matrix, it's pretty quick. &amp;nbsp;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;PRE&gt;&lt;CODE class=" language-jsl"&gt;Names Default to here(1);
dt = open("$SAMPLE_DATA\Big Class.jmp");
st1 = HPtime();
mat = :height &amp;lt;&amp;lt; Get Values;
//number of rows you want to average
x= 5;
//+- gap
z = (x-1)/2;
//get the rows
rows = 1::nrows(mat);
//mirror the rows on the front and back
mirrored = ((z+1)::2)||rows||((ncol(rows)-1)::(ncol(rows)-z));
big_mat = [];
for(i=0, i&amp;lt;=x-1, i++, 
//this is cutting up the longer mirrored vector into x vectors of the same length as the original
big_mat ||= mat[mirrored[rows+i]];
);

//now we can just take a VSum of the transpose /x to get our average
Squasher = !ismissing(big_mat); //everywhere there's a non-missing, make 1 
Squasher = VSum(Squasher`); //count real numbers, this is to not weight non-missings
A = Vsum(big_mat`)/x;
New Column("Moving Average", Set Values(A)); //If you don't need this column 
//and you're just doing matrix operations this is actually about half the total time
en1 = HPTime()-st1;



// Data Table method
st2 = HPTime();
dt&amp;lt;&amp;lt; New Column("moving sum(x)", formula(If(Row()&amp;lt;=:Moving Avg Window,
If( Row() == 1,
:height,
Lag( :Name( "moving sum(x)" ), 1 ) + :height
),
(Lag( :Name( "moving sum(x)" ), 1 ) + :height) -
Lag( :height, :Moving Avg Window )
)));
dt&amp;lt;&amp;lt; New Column("Moving Avg", Formula(
If(Row()&amp;gt;=:Moving Avg Window,
:Name( "moving sum(x)" ) / :Moving Avg Window,
.
)));
en2 = HPTime()-st2;
show(en1, en2);&lt;/CODE&gt;&lt;/PRE&gt;</description>
      <pubDate>Tue, 15 Nov 2016 21:18:17 GMT</pubDate>
      <guid>https://community.jmp.com/t5/Discussions/Efficient-moving-average-algorithm/m-p/29206#M19327</guid>
      <dc:creator>vince_faller</dc:creator>
      <dc:date>2016-11-15T21:18:17Z</dc:date>
    </item>
  </channel>
</rss>

