Averages/Simple moving average: Difference between revisions

(added K solution)
 
(89 intermediate revisions by 41 users not shown)
Line 1:
{{task|Probability and statistics}}
 
Computing the [[wp:Moving_average#Simple_moving_average|simple moving average]] of a series of numbers.
 
;Task
The task is to:
:''Create a [[wp:Stateful|stateful]] function/class/instance that takes a period and returns a routine that takes a number as argument and returns a simple moving average of its arguments so far.''
 
Create a [[wp:Stateful|stateful]] function/class/instance that takes a period and returns a routine that takes a number as argument and returns a simple moving average of its arguments so far.
'''Description'''<br>
A simple moving average is a method for computing an average of a stream of numbers by only averaging the last P numbers from the stream, where P is known as the period.
It can be implemented by calling an initialing routine with P as its argument, I(P), which should then return a routine that when called with individual, successive members of a stream of numbers, computes the mean of (up to), the last P of them, lets call this SMA().
 
{{task heading|Description}}
The word stateful in the task description refers to the need for SMA() to remember certain information between calls to it:
* The period, P
* An ordered container of at least the last P numbers from each of its individual calls.
Stateful also means that successive calls to I(), the initializer, should return separate routines that do ''not'' share saved state so they could be used on two independent streams of data.
 
A simple moving average is a method for computing an average of a stream of numbers by only averaging the last &nbsp; P &nbsp; numbers from the stream, &nbsp; where &nbsp; P &nbsp; is known as the period.
Pseudocode for an implementation of SMA is:
 
It can be implemented by calling an initialing routine with &nbsp; P &nbsp; as its argument, &nbsp; I(P), &nbsp; which should then return a routine that when called with individual, successive members of a stream of numbers, computes the mean of (up to), the last &nbsp; P &nbsp; of them, lets call this &nbsp; SMA().
 
The word &nbsp; ''stateful'' &nbsp; in the task description refers to the need for &nbsp; SMA() &nbsp; to remember certain information between calls to it:
* &nbsp; The period, &nbsp; P
* &nbsp; An ordered container of at least the last &nbsp; P &nbsp; numbers from each of its individual calls.
 
<br>
''Stateful'' &nbsp; also means that successive calls to &nbsp; I(), &nbsp; the initializer, &nbsp; should return separate routines that do &nbsp; ''not'' &nbsp; share saved state so they could be used on two independent streams of data.
 
Pseudo-code for an implementation of &nbsp; SMA &nbsp; is:
<pre>
function SMA(number: N):
Line 32 ⟶ 38:
</pre>
 
{{task heading|See also}}
 
{{Related tasks/Statistical measures}}
See also: [[Standard Deviation]]
 
<hr>
 
=={{header|11l}}==
{{trans|D}}
<syntaxhighlight lang="11l">T SMA
[Float] data
sum = 0.0
index = 0
n_filled = 0
Int period
 
F (period)
.period = period
.data = [0.0] * period
 
F add(v)
.sum += v - .data[.index]
.data[.index] = v
.index = (.index + 1) % .period
.n_filled = min(.period, .n_filled + 1)
R .sum / .n_filled
 
V sma3 = SMA(3)
V sma5 = SMA(5)
 
L(e) [1, 2, 3, 4, 5, 5, 4, 3, 2, 1]
print(‘Added #., sma(3) = #.6, sma(5) = #.6’.format(e, sma3.add(e), sma5.add(e)))</syntaxhighlight>
{{out}}
<pre>
Added 1, sma(3) = 1.000000, sma(5) = 1.000000
Added 2, sma(3) = 1.500000, sma(5) = 1.500000
Added 3, sma(3) = 2.000000, sma(5) = 2.000000
Added 4, sma(3) = 3.000000, sma(5) = 2.500000
Added 5, sma(3) = 4.000000, sma(5) = 3.000000
Added 5, sma(3) = 4.666667, sma(5) = 3.800000
Added 4, sma(3) = 4.666667, sma(5) = 4.200000
Added 3, sma(3) = 4.000000, sma(5) = 4.200000
Added 2, sma(3) = 3.000000, sma(5) = 3.800000
Added 1, sma(3) = 2.000000, sma(5) = 3.000000
</pre>
 
=={{header|360 Assembly}}==
{{trans|PL/I}}
<langsyntaxhighlight lang="360asm">* Averages/Simple moving average 26/08/2015
AVGSMA CSECT
USING AVGSMA,R12
Line 124 ⟶ 172:
EDMASK DC X'4020202020202021204B202020' CL13
YREGS
END AVGSMA</langsyntaxhighlight>
{{out}}
<pre>
Line 145 ⟶ 193:
 
moving.ads:
<langsyntaxhighlight Adalang="ada">generic
Max_Elements : Positive;
type Number is digits <>;
Line 152 ⟶ 200:
function Moving_Average (N : Number) return Number;
function Get_Average return Number;
end Moving;</langsyntaxhighlight>
 
moving.adb:
<langsyntaxhighlight Adalang="ada">with Ada.Containers.Vectors;
 
package body Moving is
Line 194 ⟶ 242:
end Moving_Average;
 
end Moving;</langsyntaxhighlight>
 
main.adb:
<langsyntaxhighlight Adalang="ada">with Ada.Text_IO;
with Moving;
procedure Main is
Line 215 ⟶ 263:
" into max-5: " & Float'Image (Five_Average.Moving_Average (Float (I))));
end loop;
end Main;</langsyntaxhighlight>
 
{{out}}
Line 248 ⟶ 296:
<!-- {{works with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8.8d.fc9.i386]}} -->
Note: This following code is a direct translation of the [[Average/Simple_moving_average#C|C]] code sample. It mimics C's var_list implementation, and so it probably isn't the most natural way of dong this actual task in '''ALGOL 68'''.
<langsyntaxhighlight Algol68lang="algol68">MODE SMAOBJ = STRUCT(
LONG REAL sma,
LONG REAL sum,
Line 335 ⟶ 383:
sma(SMAFREE(h5))
#
)</langsyntaxhighlight>
{{out}}
<pre>
Line 353 ⟶ 401:
ahk forum: [http://www.autohotkey.com/forum/post-276695.html#276695 discussion]
For Integers:
<langsyntaxhighlight AutoHotkeylang="autohotkey">MsgBox % MovingAverage(5,3) ; 5, averaging length <- 3
MsgBox % MovingAverage(1) ; 3
MsgBox % MovingAverage(-3) ; 1
Line 370 ⟶ 418:
v%i% := x, i := mod(i+1,m) ; remember last m inputs, cycle insertion point
Return sum/n
}</langsyntaxhighlight>
For floating point numbers:
<langsyntaxhighlight AutoHotkeylang="autohotkey">MovingAverage(x,len="") { ; for floating point numbers
Static
Static n:=0, m:=10 ; default averaging length = 10
Line 382 ⟶ 430:
j := A_Index-1, sum += v%j%
Return sum/n
}</langsyntaxhighlight>
 
=={{header|AWK}}==
<langsyntaxhighlight lang="awk">#!/usr/bin/awk -f
# Moving average over the first column of a data file
BEGIN {
Line 397 ⟶ 445:
Z[i] = x;
print MA;
}</langsyntaxhighlight>
 
=={{header|BBC BASIC}}==
{{works with|BBC BASIC for Windows}}
<langsyntaxhighlight lang="bbcbasic"> MAXPERIOD = 10
FOR n = 1 TO 5
PRINT "Number = ";n TAB(12) " SMA3 = ";FNsma(n,3) TAB(30) " SMA5 = ";FNsma(n,5)
Line 418 ⟶ 466:
index%(period%) = (index%(period%) + 1) MOD period%
IF window%(period%)<period% window%(period%) += 1
= accum(period%) / window%(period%)</langsyntaxhighlight>
{{out}}
<pre>
Line 432 ⟶ 480:
Number = 1 SMA3 = 2 SMA5 = 3
</pre>
 
=={{header|BQN}}==
 
<code>SMA</code> takes moving average of a list, given the whole array.
 
<code>SMA2</code> returns a stateful function which can be run on individual numbers of a stream.
 
<pre>SMA ← {(+´÷≠)¨(1↓𝕨↑↑𝕩)∾<˘𝕨↕𝕩}
 
v ← (⊢∾⌽)1+↕5
•Show 5 SMA v
 
SMA2 ← {
𝕊 size:
nums ← ⟨⟩
sum ← 0
{
nums ∾↩ 𝕩
gb ← {(≠nums)≤size ? 0 ; a←⊑nums, nums↩1↓nums, a}
sum +↩ 𝕩 - gb
sum ÷ ≠nums
}
}
 
fun ← SMA2 5
Fun¨ v</pre>
<pre>⟨ 1 1.5 2 2.5 3 3.8 4.2 4.2 3.8 3 ⟩
⟨ 1 1.5 2 2.5 3 3.8 4.2 4.2 3.8 3 ⟩</pre>
 
[https://mlochbaum.github.io/BQN/try.html#code=U01BIOKGkCB7KCvCtMO34omgKcKoKDHihpPwnZWo4oaR4oaR8J2VqSniiL48y5jwnZWo4oaV8J2VqX0KCnYg4oaQICjiiqLiiL7ijL0pMSvihpU1CuKAolNob3cgNSBTTUEgdgoKU01BMiDihpAgewogIPCdlYogc2l6ZToKICBudW1zIOKGkCDin6jin6kKICBzdW0g4oaQIDAKICB7CiAgICBudW1zIOKIvuKGqSDwnZWpCiAgICBnYiDihpAgeyjiiaBudW1zKeKJpHNpemUgPyAwIDsgYeKGkOKKkW51bXMsIG51bXPihqkx4oaTbnVtcywgYX0KICAgIHN1bSAr4oapIPCdlakgLSBnYgogICAgc3VtIMO3IOKJoG51bXMKICB9Cn0KCmZ1biDihpAgU01BMiA1CkZ1bsKoIHY= Try It!]
 
=={{header|Bracmat}}==
<langsyntaxhighlight lang="bracmat">( ( I
= buffer
. (new$=):?freshEmptyBuffer
Line 471 ⟶ 549:
$ (str$(!k " - sma3:" pad$(sma3$!k) " sma5:" pad$(sma5$!k)))
)
);</langsyntaxhighlight>
{{out}}
<pre>1 - sma3: 1 sma5: 1
Line 486 ⟶ 564:
=={{header|Brat}}==
Object version
<langsyntaxhighlight lang="brat">
SMA = object.new
 
Line 507 ⟶ 585:
[1, 2, 3, 4, 5, 5, 4, 3, 2, 1].each { n |
p n, " - SMA3: ", sma3.add(n), " SMA5: ", sma5.add(n)
}</langsyntaxhighlight>
 
Function version
 
<langsyntaxhighlight lang="brat">sma = { period |
list = []
 
Line 527 ⟶ 605:
[1, 2, 3, 4, 5, 5, 4, 3, 2, 1].each { n |
p n, " - SMA3: ", sma3(n), " SMA5: ", sma5(n)
}</langsyntaxhighlight>
 
{{out}}
Line 542 ⟶ 620:
 
=={{header|C}}==
<langsyntaxhighlight lang="c">#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
Line 610 ⟶ 688:
va_end(vl);
return r;
}</langsyntaxhighlight>
 
<langsyntaxhighlight lang="c">double v[] = { 1, 2, 3, 4, 5, 5, 4, 3, 2, 1 };
 
int main()
Line 629 ⟶ 707:
sma(SMA_FREE, h5);
return 0;
}</langsyntaxhighlight>
 
=={{header|C sharp|C#}}==
 
{{works with|C sharp|C#|3}}
 
<syntaxhighlight lang="csharp">using System;
using System.Collections.Generic;
using System.Linq;
 
namespace SMA {
class Program {
static void Main(string[] args) {
var nums = Enumerable.Range(1, 5).Select(n => (double)n);
nums = nums.Concat(nums.Reverse());
 
var sma3 = SMA(3);
var sma5 = SMA(5);
 
foreach (var n in nums) {
Console.WriteLine("{0} (sma3) {1,-16} (sma5) {2,-16}", n, sma3(n), sma5(n));
}
}
 
static Func<double, double> SMA(int p) {
Queue<double> s = new Queue<double>(p);
return (x) => {
if (s.Count >= p) {
s.Dequeue();
}
s.Enqueue(x);
return s.Average();
};
}
}
}</syntaxhighlight>
 
{{out}}
<pre>
1 (sma3) 1 (sma5) 1
2 (sma3) 1.5 (sma5) 1.5
3 (sma3) 2 (sma5) 2
4 (sma3) 3 (sma5) 2.5
5 (sma3) 4 (sma5) 3
5 (sma3) 4.66666666666667 (sma5) 3.8
4 (sma3) 4.66666666666667 (sma5) 4.2
3 (sma3) 4 (sma5) 4.2
2 (sma3) 3 (sma5) 3.8
1 (sma3) 2 (sma5) 3
</pre>
 
=={{header|C++}}==
<langsyntaxhighlight lang="cpp">
#include <iostream>
#include <stddef.h>
Line 734 ⟶ 861:
return 0;
}
</syntaxhighlight>
</lang>
 
=={{header|C sharp|C#}}==
 
{{works with|C sharp|C#|3}}
 
<lang csharp>using System;
using System.Collections.Generic;
using System.Linq;
 
namespace SMA {
class Program {
static void Main(string[] args) {
var nums = Enumerable.Range(1, 5).Select(n => (double)n);
nums = nums.Concat(nums.Reverse());
 
var sma3 = SMA(3);
var sma5 = SMA(5);
 
foreach (var n in nums) {
Console.WriteLine("{0} (sma3) {1,-16} (sma5) {2,-16}", n, sma3(n), sma5(n));
}
}
 
static Func<double, double> SMA(int p) {
Queue<double> s = new Queue<double>(p);
return (x) => {
if (s.Count >= p) {
s.Dequeue();
}
s.Enqueue(x);
return s.Average();
};
}
}
}</lang>
 
{{out}}
<pre>
1 (sma3) 1 (sma5) 1
2 (sma3) 1.5 (sma5) 1.5
3 (sma3) 2 (sma5) 2
4 (sma3) 3 (sma5) 2.5
5 (sma3) 4 (sma5) 3
5 (sma3) 4.66666666666667 (sma5) 3.8
4 (sma3) 4.66666666666667 (sma5) 4.2
3 (sma3) 4 (sma5) 4.2
2 (sma3) 3 (sma5) 3.8
1 (sma3) 2 (sma5) 3
</pre>
 
=={{header|Clojure}}==
This version uses a persistent queue to hold the most recent ''p'' values.
Each function returned from ''init-moving-average'' has its state in an atom holding a queue value.
<langsyntaxhighlight lang="clojure">(import '[clojure.lang PersistentQueue])
 
(defn enqueue-max [q p n]
Line 799 ⟶ 877:
(let [state (atom PersistentQueue/EMPTY)]
(fn [n]
(avg (swap! state enqueue-max p n)))))</langsyntaxhighlight>
 
=={{header|CoffeeScript}}==
<langsyntaxhighlight lang="coffeescript">
I = (P) ->
# The cryptic name "I" follows the problem description;
Line 847 ⟶ 925:
for i in [1..10]
console.log i, sma3(i), sma7(i), sma11(i)
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 867 ⟶ 945:
This implementation uses a circular list to store the numbers within the window; at the beginning of each iteration <var>pointer</var> refers to the list cell which holds the value just moving out of the window and to be replaced with the just-added value.
 
<langsyntaxhighlight lang="lisp">(defun simple-moving-average (period &aux
(sum 0) (count 0) (values (make-list period)) (pointer values))
(setf (rest (last values)) values) ; construct circularity
Line 877 ⟶ 955:
(setf (first pointer) n)
(setf pointer (rest pointer)) ; advance pointer
(/ sum (min count period))))</langsyntaxhighlight>
 
Use
 
<syntaxhighlight lang="lisp">(mapcar '(simple-moving-average period) list-of-values)</syntaxhighlight>
 
=={{header|Crystal}}==
<syntaxhighlight lang="ruby">def sma(n) Proc(Float64, Float64)
a = Array(Float64).new
->(x : Float64) {
a.shift if a.size == n
a.push x
a.sum / a.size.to_f
}
end
 
sma3, sma5 = sma(3), sma(5)
 
# Copied from the Ruby solution.
(1.upto(5).to_a + 5.downto(1).to_a).each do |n|
printf "%d: sma3 = %.3f - sma5 = %.3f\n", n, sma3.call(n.to_f), sma5.call(n.to_f)
end</syntaxhighlight>
 
<pre>
1: sma3 = 1.000 - sma5 = 1.000
2: sma3 = 1.500 - sma5 = 1.500
3: sma3 = 2.000 - sma5 = 2.000
4: sma3 = 3.000 - sma5 = 2.500
5: sma3 = 4.000 - sma5 = 3.000
5: sma3 = 4.667 - sma5 = 3.800
4: sma3 = 4.667 - sma5 = 4.200
3: sma3 = 4.000 - sma5 = 4.200
2: sma3 = 3.000 - sma5 = 3.800
1: sma3 = 2.000 - sma5 = 3.000
</pre>
 
=={{header|D}}==
===Using a Closure===
Currently this <code>sma</code> can't be @nogc because it allocates a closure on the heap. Some escape analysis could remove the heap allocation.
<langsyntaxhighlight lang="d">import std.stdio, std.traits, std.algorithm;
 
auto sma(T, int period)() pure nothrow @safe {
Line 904 ⟶ 1,016:
foreach (immutable e; [1, 2, 3, 4, 5, 5, 4, 3, 2, 1])
writefln("Added %d, sma(3) = %f, sma(5) = %f", e, s3(e), s5(e));
}</langsyntaxhighlight>
{{out}}
<pre>Added 1, sma(3) = 1.000000, sma(5) = 1.000000
Line 921 ⟶ 1,033:
keeping the data in the stack frame of the main function.
Same output:
<langsyntaxhighlight lang="d">import std.stdio, std.traits, std.algorithm;
 
struct SMA(T, int period) {
Line 943 ⟶ 1,055:
foreach (immutable e; [1, 2, 3, 4, 5, 5, 4, 3, 2, 1])
writefln("Added %d, sma(3) = %f, sma(5) = %f", e, s3(e), s5(e));
}</langsyntaxhighlight>
To avoid the floating point approximations keep piling up and growing, the code could perform a periodic sum on the whole circular queue array.
=={{header|Delphi}}==
{{Trans|Pascal}}
Small variation of [[#Pascal]].
<syntaxhighlight lang="delphi">
program Simple_moving_average;
 
{$APPTYPE CONSOLE}
 
type
TMovingAverage = record
private
buffer: TArray<Double>;
head: Integer;
Capacity: Integer;
Count: Integer;
sum, fValue: Double;
public
constructor Create(aCapacity: Integer);
function Add(Value: Double): Double;
procedure Reset;
property Value: Double read fValue;
end;
 
{ TMovingAverage }
 
function TMovingAverage.Add(Value: Double): Double;
begin
head := (head + 1) mod Capacity;
sum := sum + Value - buffer[head];
buffer[head] := Value;
 
if count < capacity then
begin
inc(Count);
fValue := sum / count;
exit(fValue);
end;
fValue := sum / Capacity;
Result := fValue;
end;
 
constructor TMovingAverage.Create(aCapacity: Integer);
begin
Capacity := aCapacity;
SetLength(buffer, aCapacity);
Reset;
end;
 
procedure TMovingAverage.Reset;
var
i: integer;
begin
head := -1;
Count := 0;
sum := 0;
fValue := 0;
for i := 0 to High(buffer) do
buffer[i] := 0;
end;
 
var
avg3, avg5: TMovingAverage;
i: Integer;
 
begin
avg3 := TMovingAverage.Create(3);
avg5 := TMovingAverage.Create(5);
 
for i := 1 to 5 do
begin
write('Inserting ', i, ' into avg3 ', avg3.Add(i): 0: 4);
writeln(' Inserting ', i, ' into avg5 ', avg5.Add(i): 0: 4);
end;
 
for i := 5 downto 1 do
begin
write('Inserting ', i, ' into avg3 ', avg3.Add(i): 0: 4);
writeln(' Inserting ', i, ' into avg5 ', avg5.Add(i): 0: 4);
end;
 
avg3.Reset;
for i := 1 to 100000000 do
avg3.Add(i);
writeln('100''000''000 insertions ', avg3.Value: 0: 4);
 
Readln;
end.</syntaxhighlight>
{{out}}
<pre>
Inserting 1 into avg3 1.0000 Inserting 1 into avg5 1.0000
Inserting 2 into avg3 1.5000 Inserting 2 into avg5 1.5000
Inserting 3 into avg3 2.0000 Inserting 3 into avg5 2.0000
Inserting 4 into avg3 3.0000 Inserting 4 into avg5 2.5000
Inserting 5 into avg3 4.0000 Inserting 5 into avg5 3.0000
Inserting 5 into avg3 4.6667 Inserting 5 into avg5 3.8000
Inserting 4 into avg3 4.6667 Inserting 4 into avg5 4.2000
Inserting 3 into avg3 4.0000 Inserting 3 into avg5 4.2000
Inserting 2 into avg3 3.0000 Inserting 2 into avg5 3.8000
Inserting 1 into avg3 2.0000 Inserting 1 into avg5 3.0000
100'000'000 insertions 99999999.0000
</pre>
 
=={{header|Dyalect}}==
 
{{trans|C#}}
 
<syntaxhighlight lang="dyalect">func avg(xs) {
var acc = 0.0
var c = 0
for x in xs {
c += 1
acc += x
}
acc / c
}
func sma(p) {
var s = []
x => {
if s.Length() >= p {
s.RemoveAt(0)
}
s.Insert(s.Length(), x)
avg(s)
};
}
var nums = Iterator.Concat(1.0..5.0, 5.0^-1.0..1.0)
var sma3 = sma(3)
var sma5 = sma(5)
for n in nums {
print("\(n)\t(sma3) \(sma3(n))\t(sma5) \(sma5(n))")
}</syntaxhighlight>
 
=={{header|E}}==
Line 954 ⟶ 1,200:
The structure is the same as the implementation of [[Standard Deviation#E]].
 
<langsyntaxhighlight lang="e">pragma.enable("accumulator")
def makeMovingAverage(period) {
def values := ([null] * period).diverge()
Line 975 ⟶ 1,221:
return [insert, average]
}</langsyntaxhighlight>
 
<div style="overflow: auto; max-height: 12em;"><langsyntaxhighlight lang="e">? for period in [3, 5] {
> def [insert, average] := makeMovingAverage(period)
> println(`Period $period:`)
Line 1,009 ⟶ 1,255:
3 4.2
2 3.8
1 3.0</langsyntaxhighlight></div>
 
=={{header|EasyLang}}==
<syntaxhighlight>
prefix sma_
global p[] ind[] sum[] smpl[][] .
func new p .
p[] &= p
ind[] &= 0
sum[] &= 0
smpl[][] &= [ ]
return len p[]
.
func get id x .
ind[id] = (ind[id] + 1) mod1 p[id]
ind = ind[id]
if len smpl[id][] < ind
len smpl[id][] ind
else
sum[id] -= smpl[id][ind]
.
sum[id] += x
smpl[id][ind] = x
return sum[id] / len smpl[id][]
.
prefix
#
sma5 = sma_new 5
sma3 = sma_new 3
numfmt 2 4
for v in [ 1 2 3 4 5 5 4 3 2 1 ]
print sma_get sma3 v & " " & sma_get sma5 v
.
</syntaxhighlight>
 
=={{header|EchoLisp}}==
<langsyntaxhighlight lang="scheme">
(lib 'tree) ;; queues operations
 
Line 1,023 ⟶ 1,302:
(// (for/sum ((x (queue->list Q))) x) (queue-length Q))))
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 1,045 ⟶ 1,324:
 
=={{header|Elena}}==
ELENA 6.x :
<lang elena>#define system.
#define<syntaxhighlight lang="elena">import system'routines.;
#defineimport system'collections.;
#defineimport extensions.;
 
#class SMA
{
#fieldobject thePeriod.;
#fieldobject theList.;
#constructor new : aPeriod(period)
[{
thePeriod := aPeriod.period;
theList :=new List new.();
]}
#method append : aNumber(n)
[{
theList += aNumber.append(n);
 
#var aCountcount := theList length.Length;
^ aCountcount =>
0 ? [{ ^0.0r ] }
! [{
if (aCountcount > thePeriod)?
[{
theList remove &index:0.removeAt(0);
aCountcount := thePeriod.
].};
#var aSumsum := theList .summarize:(Real .new &int:0().);
^ aSumsum / aCount.count
].}
]}
}
 
// --- Program ---
#symbol program =
[
#var SMA3 := SMA new:3.
#var SMA5 := SMA new:5.
 
public program()
1 to:5 &doEach: (:i)
{
[
var SMA3 := SMA.new(3);
console write:"sma3 + " :i :" = ": (SMA3 += i) &paddingRight:30 &with:#32.
var SMA5 := SMA.new(5);
console writeLine:"sma5 + " :i :" = ": (SMA5 += i).
].
 
5for (int i to:= 1; &doEach:i <= 5; (:i += 1) {
console.printPaddingRight(30, "sma3 + ", i, " = ", SMA3.append(i));
[
console write:.printLine("sma3sma5 + ", :i, :" = ":, SMA5.append(SMA3 += i) &paddingRight:30 &with:#32.)
};
console writeLine:"sma5 + " :i :" = ": (SMA5 += i).
 
].
for (int i := 5; i >= 1; i -= 1) {
].</lang>
console.printPaddingRight(30, "sma3 + ", i, " = ", SMA3.append(i));
console.printLine("sma5 + ", i, " = ", SMA5.append(i))
};
console.readChar()
}</syntaxhighlight>
{{out}}
<pre>
Line 1,117 ⟶ 1,398:
The elixir program below generates an anonymous function with an embedded period `p`, which is used as the period of the simple moving average. The `run` function reads numeric input and passes it to the newly created anonymous function, and then "inspects" the result to STDOUT.
 
<langsyntaxhighlight lang="elixir">$ cat simple-moving-avg.exs
#!/usr/bin/env elixir
 
Line 1,158 ⟶ 1,439:
end
 
SMA.run</langsyntaxhighlight>
 
<langsyntaxhighlight lang="bash">#!/bin/bash
elixir ./simple-moving-avg.exs <<EOF
1 2 3 4 5 6 7 8 9 8 7 6 5 4 3 2 1
2 4 6 8 10 12 14 12 10 8 6 4 2
EOF</langsyntaxhighlight>
 
The output is shown below, with the average, followed by the grouped input, forming the basis of each moving average.
Line 1,212 ⟶ 1,493:
 
=={{header|Erlang}}==
<langsyntaxhighlight lang="erlang">main() ->
SMA3 = sma(3),
SMA5 = sma(5),
Line 1,252 ⟶ 1,533:
{average, Ave} ->
Ave
end.</langsyntaxhighlight>
 
{{out}}
<langsyntaxhighlight lang="erlang">9> sma:main().
Added 1, sma(3) -> 1.000000, sma(5) -> 1.000000
Added 2, sma(3) -> 1.500000, sma(5) -> 1.500000
Line 1,266 ⟶ 1,547:
Added 2, sma(3) -> 3.000000, sma(5) -> 3.800000
Added 1, sma(3) -> 2.000000, sma(5) -> 3.000000
ok</langsyntaxhighlight>
 
Erlang has closures, but immutable variables. A solution then is to use processes and a simple message passing based API.
Line 1,274 ⟶ 1,555:
Matrix languages have routines to compute the gliding avarages for a given sequence of items.
 
<syntaxhighlight lang="euler math toolbox">
<lang Euler Math Toolbox>
>n=1000; m=100; x=random(1,n);
>x10=fold(x,ones(1,m)/m);
>x10=fftfold(x,ones(1,m)/m)[m:n]; // more efficient
</syntaxhighlight>
</lang>
 
It is less efficient to loop as in the following commands.
 
<syntaxhighlight lang="euler math toolbox">
<lang Euler Math Toolbox>
>function store (x:number, v:vector, n:index) ...
$if cols(v)<n then return v|x;
Line 1,313 ⟶ 1,594:
>v
[ 11 12 13 14 15 16 17 18 19 20 ]
</syntaxhighlight>
</lang>
 
=={{header|F_Sharp|F#}}==
<langsyntaxhighlight lang="fsharp">let sma period f (list:float list) =
let sma_aux queue v =
let q = Seq.truncate period (v :: queue)
Line 1,329 ⟶ 1,610:
printf "\nsma5: "
[ 1.;2.;3.;4.;5.;5.;4.;3.;2.;1.] |> sma 5 (printf "%.2f ")
printfn ""</langsyntaxhighlight>
{{out}}
<pre>sma3: 1.00 1.50 2.00 3.00 4.00 4.67 4.67 4.00 3.00 2.00
sma5: 1.00 1.50 2.00 2.50 3.00 3.80 4.20 4.20 3.80 3.00</pre>
 
=={{header|Factor}}==
The <code>I</code> word creates a quotation (anonymous function) that closes over a sequence and a period. This quotation handles adding/removing numbers to the simple moving average (SMA). We can then add a number to the SMA using <code>sma-add</code> and get the SMA's sequence and mean with <code>sma-query</code>. Quotations adhere to the <code>sequence</code> protocol so we can obtain the sequence of numbers simply by calling <code>first</code> on the SMA quotation.
<syntaxhighlight lang="factor">USING: kernel interpolate io locals math.statistics prettyprint
random sequences ;
IN: rosetta-code.simple-moving-avg
 
:: I ( P -- quot )
V{ } clone :> v!
[ v swap suffix! P short tail* v! ] ;
 
: sma-add ( quot n -- quot' ) swap tuck call( x x -- x ) ;
 
: sma-query ( quot -- avg v ) first concat dup mean swap ;
 
: simple-moving-average-demo ( -- )
5 I 10 <iota> [
over sma-query unparse
[I After ${2} numbers Sequence is ${0} Mean is ${1}I] nl
100 random sma-add
] each drop ;
 
MAIN: simple-moving-average-demo</syntaxhighlight>
{{out}}
<pre>
After 0 numbers Sequence is V{ } Mean is 0
After 1 numbers Sequence is V{ 41 } Mean is 41
After 2 numbers Sequence is V{ 41 31 } Mean is 36
After 3 numbers Sequence is V{ 41 31 2 } Mean is 24+2/3
After 4 numbers Sequence is V{ 41 31 2 24 } Mean is 24+1/2
After 5 numbers Sequence is V{ 41 31 2 24 70 } Mean is 33+3/5
After 6 numbers Sequence is V{ 31 2 24 70 80 } Mean is 41+2/5
After 7 numbers Sequence is V{ 2 24 70 80 96 } Mean is 54+2/5
After 8 numbers Sequence is V{ 24 70 80 96 84 } Mean is 70+4/5
After 9 numbers Sequence is V{ 70 80 96 84 7 } Mean is 67+2/5
</pre>
 
=={{header|Fantom}}==
 
<langsyntaxhighlight lang="fantom">
class MovingAverage
{
Line 1,382 ⟶ 1,699:
}
}
</syntaxhighlight>
</lang>
 
{{out}} for a period of 5:
Line 1,399 ⟶ 1,716:
 
=={{header|Forth}}==
<langsyntaxhighlight lang="forth">: f+! ( f addr -- ) dup f@ f+ f! ;
: ,f0s ( n -- ) falign 0 do 0e f, loop ;
 
Line 1,425 ⟶ 1,742:
2e sma f. \ 1.5
3e sma f. \ 2.
4e sma f. \ 3.</langsyntaxhighlight>
 
=={{header|Fortran}}==
{{works with|Fortran|90 and later}}
<langsyntaxhighlight lang="fortran">program Movavg
implicit none
 
Line 1,461 ⟶ 1,778:
end function
 
end program Movavg</langsyntaxhighlight>
 
=={{header|FreeBASIC}}==
<syntaxhighlight lang="freebasic">' FB 1.05.0 Win64
 
Type FuncType As Function(As Double) As Double
 
' These 'shared' variables are available to all functions defined below
Dim Shared p As UInteger
Dim Shared list() As Double
 
Function sma(n As Double) As Double
Redim Preserve list(0 To UBound(list) + 1)
list(UBound(list)) = n
Dim start As Integer = 0
Dim length As Integer = UBound(list) + 1
If length > p Then
start = UBound(list) - p + 1
length = p
End If
Dim sum As Double = 0.0
For i As Integer = start To UBound(list)
sum += list(i)
Next
Return sum / length
End Function
Function initSma(period As Uinteger) As FuncType
p = period
Erase list '' ensure the array is empty on each initialization
Return @sma
End Function
 
Dim As FuncType ma = initSma(3)
Print "Period = "; p
Print
For i As Integer = 0 To 9
Print "Add"; i; " => moving average ="; ma(i)
Next
Print
ma = initSma(5)
Print "Period = "; p
Print
For i As Integer = 9 To 0 Step -1
Print "Add"; i; " => moving average ="; ma(i)
Next
Print
Print "Press any key to quit"
Sleep</syntaxhighlight>
 
{{out}}
<pre>
Period = 3
 
Add 0 => moving average = 0
Add 1 => moving average = 0.5
Add 2 => moving average = 1
Add 3 => moving average = 2
Add 4 => moving average = 3
Add 5 => moving average = 4
Add 6 => moving average = 5
Add 7 => moving average = 6
Add 8 => moving average = 7
Add 9 => moving average = 8
 
Period = 5
 
Add 9 => moving average = 9
Add 8 => moving average = 8.5
Add 7 => moving average = 8
Add 6 => moving average = 7.5
Add 5 => moving average = 7
Add 4 => moving average = 6
Add 3 => moving average = 5
Add 2 => moving average = 4
Add 1 => moving average = 3
Add 0 => moving average = 2
</pre>
 
=={{header|GAP}}==
<langsyntaxhighlight lang="gap">MovingAverage := function(n)
local sma, buffer, pos, sum, len;
buffer := List([1 .. n], i -> 0);
Line 1,489 ⟶ 1,884:
f(3); # 4
f(2); # 3
f(1); # 2</langsyntaxhighlight>
 
=={{header|Go}}==
<langsyntaxhighlight lang="go">package main
 
import "fmt"
 
func sma(nperiod int) func(float64) float64 {
var i int
s := make([]float64, 0, n)
i,var sum, rn := 0, 0., 1/float64(n)
returnvar func(xstorage float64)= make([]float64, {0, period)
 
if len(s) < n {
return func(input float64) (avrg float64) {
sum += x
if len(storage) < period s = append(s, x){
return sum /+= float64(len(s))input
storage = append(storage, input)
}
 
s[i] = x
sum += input - storage[i]
i++
ifstorage[i], i == ninput, {(i+1)%period
avrg = sum / float64(len(storage))
i = 0
 
}
return
sum = 0
for _, x = range s {
sum += x
}
return sum * rn
}
}
Line 1,524 ⟶ 1,917:
fmt.Printf("%5.3f %5.3f %5.3f\n", x, sma3(x), sma5(x))
}
}</langsyntaxhighlight>
{{out}}
<pre>
Line 1,542 ⟶ 1,935:
=={{header|Groovy}}==
{{trans|Ruby}}
<langsyntaxhighlight lang="groovy">def simple_moving_average = { size ->
def nums = []
double total = 0.0
Line 1,556 ⟶ 1,949:
 
(1..5).each{ printf( "%1.1f ", ma5(it)) }
(5..1).each{ printf( "%1.1f ", ma5(it)) }</langsyntaxhighlight>
{{out}}
<pre>1.0 1.5 2.0 2.5 3.0 3.8 4.2 4.2 3.8 3.0 </pre>
Line 1,563 ⟶ 1,956:
Conform version to the requirement, function SMA called multiple times with just a number:
{{works with|GHC|6.10.4}}
<syntaxhighlight lang="haskell">{-# LANGUAGE BangPatterns #-}
<lang Haskell>import Control.Monad
 
import Control.Monad
import Data.List
import Data.IORef
 
data Pair a b = Pair !a !b
 
mean :: Fractional a => [a] -> a
mean = divl . foldl' (\(Pair s l) x -> Pair (s+x) (l+1)) (Pair 0.0 0)
mean xs = sum xs / (genericLength xs)
where divl (_,0) = 0.0
divl (s,l) = s / fromIntegral l
 
series = [1,2,3,4,5,5,4,3,2,1]
 
mkSMA :: Int -> IO (Double -> IO Double)
simple_moving_averager period = do
mkSMA period numsRef= avgr <-$> newIORef []
where avgr nsref x = readIORef nsref >>= (\ns ->
return (\x -> do
numslet <-xs readIORef= numsReftake period (x:ns)
letin xswriteIORef =nsref takexs period$> (x:numsmean xs)
writeIORef numsRef xs
return $ mean xs
)
 
main = mkSMA 3 >>= (\sma3 -> mkSMA 5 >>= (\sma5 ->
main = do
mapM_ (str <$> pure n <*> sma3 <*> sma5) series))
sma3 <- simple_moving_averager 3
where str n mm3 mm5 =
sma5 <- simple_moving_averager 5
concat ["Next number = ",show n,", SMA_3 = ",show mm3,", SMA_5 = ",show mm5]</syntaxhighlight>
forM_ series (\n -> do
mm3 <- sma3 n
mm5 <- sma5 n
putStrLn $ "Next number = " ++ (show n) ++ ", SMA_3 = " ++ (show mm3) ++ ", SMA_5 = " ++ (show mm5)
)</lang>
{{out}}
<pre>Next number = 1.0, SMA_3 = 1.0, SMA_5 = 1.0
Line 1,603 ⟶ 1,995:
 
{{works with|GHC|6.10.4}}
<langsyntaxhighlight Haskelllang="haskell">import Data.List
import Control.Arrow
import Control.Monad
Line 1,612 ⟶ 2,004:
 
printSMA n p = mapM_ (\(n,a) -> putStrLn $ "Next number: " ++ show n ++ " Average: " ++ show a)
. take n . sMA p $ [1..5]++[5,4..1]++[3..]</langsyntaxhighlight>
 
Stateful function using the state monad to keep track of state
 
{{works with|GHC|7.8.3}}
<syntaxhighlight lang="haskell">
<lang Haskell>
import Control.Monad
import Control.Monad.State
Line 1,643 ⟶ 2,035:
 
main :: IO ()
main = putStrLnprint $ (showevalState result)demostrateSMA []
</syntaxhighlight>
where
(result, _) = runState demostrateSMA []
</lang>
 
{{out}}
Line 1,654 ⟶ 2,044:
 
=={{header|HicEst}}==
<langsyntaxhighlight HicEstlang="hicest">REAL :: n=10, nums(n)
 
nums = (1,2,3,4,5, 5,4,3,2,1)
Line 1,679 ⟶ 2,069:
Past(Periods(ID)) = num
SMA = SUM(Past) / MIN( now(ID), Periods(ID) )
END</langsyntaxhighlight>
<pre>num=1 SMA3=1 SMA5=1
num=2 SMA3=1.5 SMA5=1.5
Line 1,691 ⟶ 2,081:
num=10 SMA3=2 SMA5=3</pre>
 
== {{header|Icon}} and {{header|Unicon}} ==
<langsyntaxhighlight lang="unicon">procedure main(A)
sma := buildSMA(3) # Use better name than "I".
every write(sma(!A))
Line 1,709 ⟶ 2,099:
}
return (@c, c)
end</langsyntaxhighlight>
Note: This program uses Unicon specific co-expression calling syntax. It can be easily modified to run under Icon.
 
Line 1,730 ⟶ 2,120:
If the <tt>Utils</tt> package is imported from the [https://tapestry.tucson.az.us/unilib Unicon code library] then a (Unicon only) solution is:
 
<langsyntaxhighlight Uniconlang="unicon">import Utils
 
procedure main(A)
Line 1,743 ⟶ 2,133:
every (avg := 0.0) +:= !stream
return avg / *stream
end</langsyntaxhighlight>
 
with the sample run:
Line 1,767 ⟶ 2,157:
In that context, moving average is expressed very concisely in J as '''<code>(+/%#)\</code>''', though it is worth noting that this approach does not provide averages for the initial cases where not all data would be available yet:
 
<langsyntaxhighlight Jlang="j"> 5 (+/%#)\ 1 2 3 4 5 5 4 3 2 1 NB. not a solution for this task
3 3.8 4.2 4.2 3.8 3</langsyntaxhighlight>
 
In the context of the task, we need to produce a stateful function to consume streams. Since J does not have native lexical closure, we need to [http://www.jsoftware.com/jwiki/Guides/Lexical%20Closure implement it]. Thus the [[Talk:Averages/Simple_moving_average#J_Implementation|streaming solution]] is more complex:
<langsyntaxhighlight lang="j"> lex =: 1 :'(a[n__a=.m#_.[a=.18!:3$~0)&(4 :''(+/%#)(#~1-128!:5)n__x=.1|.!.y n__x'')'</langsyntaxhighlight>
'''Example:'''
<langsyntaxhighlight lang="j"> sma =: 5 lex
sma&> 1 2 3 4 5 5 4 3 2 1
1 1.5 2 2.5 3 3.8 4.2 4.2 3.8 3</langsyntaxhighlight>
Here, the <code>&></code> is analogous to the "for each" of other languages.
 
Or, a more traditional approach could be used:
 
<langsyntaxhighlight lang="j">avg=: +/ % #
SEQ=:''
moveAvg=:4 :0"0
Line 1,788 ⟶ 2,178:
 
5 moveAvg 1 2 3 4 5 5 4 3 2 1
1 1.5 2 2.5 3 3.8 4.2 4.2 3.8 3</langsyntaxhighlight>
 
=={{header|Java}}==
{{works with|Java|1.5+}}
<langsyntaxhighlight lang="java5">import java.util.LinkedList;
import java.util.Queue;
 
public class MovingAverage {
private final Queue<Double> window = new LinkedList<Double>();
Line 1,813 ⟶ 2,204:
 
public double getAvg() {
if (window.isEmpty()) return 0.0; // technically the average is undefined
return sum / window.size();
}
 
public static void main(String[] args) {
double[] testData = {1, 2, 3, 4, 5, 5, 4, 3, 2, 1};
int[] windowSizes = {3, 5};
for (int windSize : windowSizes) {
MovingAverage ma = new MovingAverage(windSize);
Line 1,829 ⟶ 2,220:
}
}
}</langsyntaxhighlight>
{{out}}
<pre>Next number = 1.0, SMA = 1.0
Line 1,855 ⟶ 2,246:
=={{header|JavaScript}}==
===Using for loop===
<langsyntaxhighlight lang="javascript">function simple_moving_averager(period) {
var nums = [];
return function(num) {
Line 1,878 ⟶ 2,269:
// using WSH
WScript.Echo("Next number = " + n + ", SMA_3 = " + sma3(n) + ", SMA_5 = " + sma5(n));
}</langsyntaxhighlight>
{{out}}
<pre>Next number = 1, SMA_3 = 1, SMA_5 = 1
Line 1,892 ⟶ 2,283:
 
===Using reduce/filter===
{{incorrect|Javascript|routine is called with a list of multiple numbers rather than being called with individual numbers in succession.}}
[http://jsfiddle.net/79xe381e/ JS Fiddle]
 
<langsyntaxhighlight lang="javascript">// single-sided
Array.prototype.simpleSMA=function(N) {
return this.map(function(x,i,v) {
function(el,index, _arr) {
if(i<N-1) return NaN;
return _arr.filter(
return v.filter(function(x2,i2) { return i2<=i && i2>i-N; }).reduce(function(a,b){ return a+b; })/N;
function(x2,i2) {
}); };
return i2 <= index && i2 > index - N;
})
.reduce(
function(current, last, index, arr){
return (current + last);
})/index || 1;
});
};
 
g=[0,1,2,3,4,5,6,7,8,59,410];
console.log(g.simpleSMA(3));
console.log(g.simpleSMA(5))</lang>;
console.log(g.simpleSMA(g.length));</syntaxhighlight>
{{out}}
<pre>
<pre>[NaN, NaN, 2, 3, 4, 5.666666666666667, 6, 5.666666666666667]
[NaN1, NaN1, NaN1.5, NaN2, 32.25, 42.4, 2.5, 52.5714285714285716, 2.625, 2.6666666666666665, 2.7]</pre>
[1, 1, 1.5, 2, 2.5, 3, 3.3333333333333335, 3.5714285714285716, 3.75, 3.888888888888889, 4]
[1, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5]
</pre>
 
=={{header|jq}}==
'''Works with jq, the C implementation of jq'''
 
'''Works with gojq, the Go implementation of jq'''
 
'''Works with jaq, the Rust implementation of jq'''
 
jq functions are stateless, so in this entry, sma($x) is defined
as a parameterized jq filter that takes as input the relevant state as a JSON object.
This should initially include a key named "period" specifying the period,
which may be infinite, i.e. the jq value `infinite` corresponding to positive infinity.
 
For example the initial call to sma/1 might look like:
<pre>
{period: infinite} | sma(100)
</pre>
Two examples are given, one with a finite and the other with an infinite period.
Both compute the average of the 11 numbers 0, 1, ... 10, by calling sma(0) and then sma(1), and so on.
<syntaxhighlight lang="jq">
# The input should be a JSON object with a key named "period".
# The output is a JSON object with a key named "average" giving the SMA.
def sma($x):
def average:
.n as $n
| if $n == null or $n == 0 then . + {n: 1, average: $x}
else .average |= (. * $n + $x) / ($n + 1)
| .n += 1
end;
if . == null or (.period and .period < 1)
then "The initial call to sma/1 must specify the period properly" | error
elif .n and .n < 0 then "Invalid value of .n" | error
elif (.period | isinfinite) then average
elif .n == null or .n == 0 then . + {n: 1, average: $x, array: [$x]}
else .n as $n
| if $n < .period
then .array += [$x]
| .n += 1
else .array |= .[1:] + [$x]
end
| .average = (.array | (add/length))
end;
 
# Call sma($x) for the 11 numbers 0, 1, ... 10.
def example($period):
reduce range(0;11) as $x({period: $period}; sma($x))
| .average ;
 
example(11), example(infinite)
</syntaxhighlight>
{{output}}
<pre>
5
5
</pre>
 
=={{header|Julia}}==
<syntaxhighlight lang="julia">using Statistics</syntaxhighlight>
A short version that buffers all numbers seen from the start.
The function wants specified the type of the data in the buffer and, if you want, the limit of the buffer.
<lang Julia>SMA(N) = let buffer = Number[]
<syntaxhighlight lang="julia">function movingaverage(::Type{T} = Float64; lim::Integer = -1) where T<:Real
x -> (push!(buffer, x) ; mean(buffer[max(1,end-N+1):end]))
buffer = Vector{T}(0)
end</lang>
if lim == -1
A version with a buffer of size at most N. An initial value can be
provided # for theunlimited buffer.
return (y::T) -> begin
<lang Julia>SMA(N, buffer = Number[]) =
push!(buffer, y)
x -> begin
return push!mean(buffer, x)
end
if length(buffer) == N+1 shift!(buffer) end
else
mean(buffer)
# limited size buffer
end</lang>
return (y) -> begin
{{Out}}
push!(buffer, y)
<pre>julia> test = SMA(3) ; test(1), test(2), test(3), test(4), test(5)
if length(buffer) > lim shift!(buffer) end
(1.0,1.5,2.0,3.0,4.0)</pre>
return mean(buffer)
end
end
end
 
test = movingaverage()
@show test(1.0) # mean([1])
@show test(2.0) # mean([1, 2])
@show test(3.0) # mean([1, 2, 3])</syntaxhighlight>
 
{{out}}
<pre>test(1.0) = 1.0
test(2.0) = 1.5
test(3.0) = 2.0</pre>
 
=={{header|K}}==
 
Non-stateful:
<lang K>
<syntaxhighlight lang="k">
v:v,|v:1+!5
v
1 2 3 4 5 5 4 3 2 1
m_avgavg:{n:-(y&#:)' m:x@,\!#x; {(+/0.0$$x)%#x}'n#'m}
sma:{avg'x@(,\!y),(1+!y)+\:!y}
m_avg[v;5]
1 1.5 2 2.5 3 3.8 4.2 4.2 3.8 3.0
sma[v;5]
</lang>
1 1.5 2 2.5 3 3.8 4.2 4.2 3.8 3
</syntaxhighlight>
 
Stateful:
<syntaxhighlight lang="k">
sma:{n::x#_n; {n::1_ n,x; {avg x@&~_n~'x} n}}
sma[5]' v
1 1.5 2 2.5 3 3.8 4.2 4.2 3.8 3
</syntaxhighlight>
 
=={{header|Kotlin}}==
<syntaxhighlight lang="scala">// version 1.0.6
 
fun initMovingAverage(p: Int): (Double) -> Double {
if (p < 1) throw IllegalArgumentException("Period must be a positive integer")
val list = mutableListOf<Double>()
return {
list.add(it)
if (list.size > p) list.removeAt(0)
list.average()
}
}
 
fun main(args: Array<String>) {
val sma4 = initMovingAverage(4)
val sma5 = initMovingAverage(5)
val numbers = listOf(1.0, 2.0, 3.0, 4.0, 5.0, 5.0, 4.0, 3.0, 2.0, 1.0)
println("num\tsma4\tsma5\n")
for (number in numbers) println("${number}\t${sma4(number)}\t${sma5(number)}")
}</syntaxhighlight>
 
{{out}}
<pre>
num sma4 sma5
 
1.0 1.0 1.0
2.0 1.5 1.5
3.0 2.0 2.0
4.0 2.5 2.5
5.0 3.5 3.0
5.0 4.25 3.8
4.0 4.5 4.2
3.0 4.25 4.2
2.0 3.5 3.8
1.0 2.5 3.0
</pre>
 
=={{header|Lasso}}==
{{incorrect|Lasso|routine is called with a list of multiple numbers rather than being called with individual numbers in succession.}}
<langsyntaxhighlight Lassolang="lasso">define simple_moving_average(a::array,s::integer)::decimal => {
#a->size == 0 ? return 0.00
#s == 0 ? return 0.00
Line 1,971 ⟶ 2,491:
', SMA5 is: ' + simple_moving_average(#mynumbers,5)
'\r'
^}</langsyntaxhighlight>
 
{{out}}
Line 1,992 ⟶ 2,512:
The interesting thing here is how to implement an equivalent of a stateful function.
For sample output see http://libertybasic.conforums.com/index.cgi?board=open&action=display&num=1322956720
<syntaxhighlight lang="lb">
<lang lb>
dim v$( 100) ' Each array term stores a particular SMA of period p in p*10 bytes
 
Line 2,061 ⟶ 2,581:
if k <Period then SMA =total / k else SMA =total /Period
end function
</syntaxhighlight>
</lang>
 
=={{header|Logo}}==
Although Logo does not support closures, some varieties of Logo support enough metaprogramming to accomplish this task.
Line 2,071 ⟶ 2,590:
UCB Logo has a DEFINE primitive to construct functions from structured instruction lists. In addition, UCB Logo supports a compact template syntax for quoting lists (backquote "`") and replacing components of quoted lists (comma ","). These facilities can be used together in order to create templated function-defining-functions.
 
<langsyntaxhighlight lang="logo">to average :l
output quotient apply "sum :l count :l
end
Line 2,093 ⟶ 2,612:
 
; the internal queue is in the global namespace, easy to inspect
show :avg3.queue ; [3 4 5]</langsyntaxhighlight>
 
If namespace pollution is a concern, UCB Logo supplies a GENSYM command to obtain unique names in order to avoid collisions.
 
<langsyntaxhighlight lang="logo"> ...
localmake "qn word :name gensym
...
Line 2,103 ⟶ 2,622:
; list user-defined functions and variables
show procedures ; [average avg3 make.sma]
show names ; [[[] [avg3.g1]]</langsyntaxhighlight>
 
=={{header|Lua}}==
 
<syntaxhighlight lang="lua">function sma(period)
<lang lua>do
local t = {}
function sum(t)
function f(a, b, ...) if b then return f(a+b, ...) else return a end end
sum = 0
function average(n)
for _, v in ipairs(t) do
if #t == 10 then table.remove(t, 1) end
sum = t[#tsum + 1] = nv
end
return f(unpack(t)) / #t
return sum
end
end
function average(n)
if #t == period then table.remove(t, 1) end
t[#t + 1] = n
return sum(t) / #t
end
return average
end
 
for v=1,30 do print(average(v)) end</lang>
sma5 = sma(5)
sma10 = sma(10)
print("SMA 5")
for v=1,15 do print(sma5(v)) end
print("\nSMA 10")
for v=1,15 do print(sma10(v)) end
</syntaxhighlight>
 
=={{header|Mathematica}} / {{header|Wolfram Language}}==
This version uses a list entry so it can use the built-in function.
<langsyntaxhighlight Mathematicalang="mathematica">MA[x_List, r_] := Join[Table[Mean[x[[1;;y]]],{y,r-1}], MovingAverage[x,r]]</langsyntaxhighlight>
 
This version is stateful instead.
<langsyntaxhighlight Mathematicalang="mathematica">MAData = {{}, 0};
MAS[x_, t_: Null] :=
With[{r = If[t === Null, MAData[[2]], t]},
Mean[MAData[[1]] =
If[Length[#] > (MAData[[2]] = r), #[[-r ;; -1]], #] &@
Append[MAData[[1]], x]]]</langsyntaxhighlight>
 
Tests:
Line 2,150 ⟶ 2,683:
 
Matlab and Octave provide very efficient and fast functions, that can be applied to vectors (i.e. series of data samples)
<langsyntaxhighlight Matlablang="matlab"> [m,z] = filter(ones(1,P),P,x); </langsyntaxhighlight>
m is the moving average, z returns the state at the end of the data series, which can be used to continue the moving average.
<langsyntaxhighlight Matlablang="matlab"> [m,z] = filter(ones(1,P),P,x,z); </langsyntaxhighlight>
 
=={{header|Mercury}}==
In Mercury, an idiomatic "moving averages" function would be 'stateless' - or rather, it would have ''explicit state'' that its callers would have to thread through uses of it:
 
<langsyntaxhighlight Mercurylang="mercury"> % state(period, list of floats from [newest, ..., oldest])
:- type state ---> state(int, list(float)).
 
Line 2,166 ⟶ 2,699:
sma(N, Average, state(P, L0), state(P, L)) :-
take_upto(P, [N|L0], L),
Average = foldl((+), L, 0.0) / float(length(L)).</langsyntaxhighlight>
 
Some notes about this solution: unless P = 0, length(L) can never be 0, as L always incorporates at least N (a step that is accomplished in the arguments to list.take_upto/3). If the implementation of the 'state' type is hidden, and if init/1 checks for P = 0, users of this code can never cause a division-by-zero error in sma/4. Although this solution doesn't try to be as stateful as the task description would like, explicit state is by far simpler and more natural and more straightforward than the alternative in Mercury. Finally, [http://www.mercury.csse.unimelb.edu.au/information/doc-release/mercury_ref/State-variables.html#State-variables state variables] (and higher-order functions that anticipate threaded state) remove much of the potential ugliness or error in threading the same state through many users.
 
=={{header|MiniScript}}==
 
We define an SMA class, which can be configured with the desired window size (P).
<syntaxhighlight lang="miniscript">SMA = {}
SMA.P = 5 // (a default; may be overridden)
SMA.buffer = null
SMA.next = function(n)
if self.buffer == null then self.buffer = []
self.buffer.push n
if self.buffer.len > self.P then self.buffer.pull
return self.buffer.sum / self.buffer.len
end function
 
sma3 = new SMA
sma3.P = 3
sma5 = new SMA
 
for i in range(10)
num = round(rnd*100)
print "num: " + num + " sma3: " + sma3.next(num) + " sma5: " + sma5.next(num)
end for</syntaxhighlight>
 
{{out}}
<pre>num: 81 sma3: 81 sma5: 81
num: 82 sma3: 81.5 sma5: 81.5
num: 78 sma3: 80.333333 sma5: 80.333333
num: 54 sma3: 71.333333 sma5: 73.75
num: 94 sma3: 75.333333 sma5: 77.8
num: 8 sma3: 52 sma5: 63.2
num: 40 sma3: 47.333333 sma5: 54.8
num: 98 sma3: 48.666667 sma5: 58.8
num: 48 sma3: 62 sma5: 57.6
num: 41 sma3: 62.333333 sma5: 47
num: 94 sma3: 61 sma5: 64.2</pre>
 
=={{header|NetRexx}}==
{{trans|Java}}
<langsyntaxhighlight NetRexxlang="netrexx">/* NetRexx */
options replace format comments java crossref symbols nobinary
 
Line 2,235 ⟶ 2,803:
run_samples(args)
return
</syntaxhighlight>
</lang>
{{out}}
<pre style="height: 25ex; overflow: scroll">
Line 2,263 ⟶ 2,831:
 
=={{header|Nim}}==
<langsyntaxhighlight lang="nim">import queuesdeques
 
proc simplemovingaverage(period: int): auto =
Line 2,270 ⟶ 2,838:
var
summ, n = 0.0
values: = initQueueDeque[float]()
for i in 1..period:
values.addaddLast(0)
 
proc sma(x: float): float =
values.addaddLast(x)
summ += x - values.dequeuepopFirst()
n = min(n+1, float(period))
result = summ / n
Line 2,290 ⟶ 2,858:
var sma2 = simplemovingaverage(5)
for i in 1..5: echo sma2(float(i))
for i in countdown(5,1): echo sma2(float(i))</langsyntaxhighlight>
{{out}}
<pre>1.0000000000000000e+000
1.5
1.5000000000000000e+00
2.0
2.0000000000000000e+00
3.0
3.0000000000000000e+00
4.0
4.0000000000000000e+00
4.666666666666667
4.6666666666666670e+00
4.666666666666667
4.6666666666666670e+00
4.0
4.0000000000000000e+00
3.0
3.0000000000000000e+00
2.0
2.0000000000000000e+00
 
1.0
1.0000000000000000e+00
1.5
1.5000000000000000e+00
2.0
2.0000000000000000e+00
2.5
2.5000000000000000e+00
3.0
3.0000000000000000e+00
3.8
3.7999999999999998e+00
4.2
4.2000000000000002e+00
4.2
4.2000000000000002e+00
3.8
3.7999999999999998e+00
3.0000000000000000e+000</pre>
 
=={{header|Objeck}}==
{{trans|Java}}
<langsyntaxhighlight lang="objeck">
use Collection;
 
Line 2,362 ⟶ 2,930:
}
}
</syntaxhighlight>
</lang>
 
{{out}}
Line 2,391 ⟶ 2,959:
=={{header|Objective-C}}==
 
<langsyntaxhighlight lang="objc">#import <Foundation/Foundation.h>
 
@interface MovingAverage : NSObject {
Line 2,484 ⟶ 3,052:
}
return 0;
}</langsyntaxhighlight>
 
{{out}}
Line 2,512 ⟶ 3,080:
 
=={{header|OCaml}}==
<langsyntaxhighlight lang="ocaml">let sma (n, s, q) x =
let l = Queue.length q and s = s +. x in
Queue.push x q;
Line 2,536 ⟶ 3,104:
);
print_newline ();
) periodLst</langsyntaxhighlight>
 
{{out}}
Line 2,566 ⟶ 3,134:
 
More imperatively:
<langsyntaxhighlight lang="ocaml">let sma_create period =
let q = Queue.create ()
and sum = ref 0.0 in
Line 2,587 ⟶ 3,155:
) series;
print_newline ();
) periodLst</langsyntaxhighlight>
 
=={{header|Oforth}}==
 
createSMA returns a closure.
The list of values is included into a channel so this code is thread-safe : multiple tasks running in parallel can call the closure returned.
 
<syntaxhighlight lang="oforth">import: parallel
 
: createSMA(period)
| ch |
Channel new [ ] over send drop ->ch
#[ ch receive + left(period) dup avg swap ch send drop ] ;</syntaxhighlight>
 
Usage:
 
<syntaxhighlight lang="oforth">: test
| sma3 sma5 l |
3 createSMA -> sma3
5 createSMA -> sma5
[ 1, 2, 3, 4, 5, 5, 4, 3, 2, 1 ] ->l
"SMA3" .cr l apply( #[ sma3 perform . ] ) printcr
"SMA5" .cr l apply( #[ sma5 perform . ] ) ;</syntaxhighlight>
 
{{out}}
<pre>
>test
SMA3
1 1.5 2 3 4 4.66666666666667 4.66666666666667 4 3 2
SMA5
1 1.5 2 2.5 3 3.8 4.2 4.2 3.8 3 ok
</pre>
 
=={{header|ooRexx}}==
ooRexx does not have stateful functions, but the same effect can be achieved by using object instances.
<syntaxhighlight lang="oorexx">
<lang ooRexx>
testdata = .array~of(1, 2, 3, 4, 5, 5, 4, 3, 2, 1)
 
Line 2,634 ⟶ 3,233:
-- return current queue
return sum / queue~items
</syntaxhighlight>
</lang>
{{out}}
<pre>
Line 2,665 ⟶ 3,264:
 
=={{header|OxygenBasic}}==
<langsyntaxhighlight lang="oxygenbasic">def max 1000
 
Class MovingAverage
Line 2,707 ⟶ 3,306:
'...
print A.average 'reult 95
</syntaxhighlight>
</lang>
 
=={{header|Oz}}==
<langsyntaxhighlight lang="oz">declare
 
fun {CreateSMA Period}
Line 2,736 ⟶ 3,335:
{System.showInfo " Number = "#I#" , SMA = "#{SMA {Int.toFloat I}}}
end
end</langsyntaxhighlight>
 
=={{header|PARI/GP}}==
Partial implementation: does not (yet?) create different stores on each invocation.
<langsyntaxhighlight lang="parigp">sma_per(n)={
sma_v=vector(n);
sma_i = 0;
n->if(sma_i++>#sma_v,sma_v[sma_i=1]=n;0,sma_v[sma_i]=n;0)+sum(i=1,#sma_v,sma_v[i])/#sma_v
};</langsyntaxhighlight>
 
=={{header|Pascal}}==
{{works with|Free Pascal}}
Like in other implementations the sum of the last p values is only updated by subtracting the oldest value and addindg the new. To minimize rounding errors after p values the sum is corrected to the real sum.
<langsyntaxhighlight Pascallang="pascal">program sma;
type
tsma = record
Line 2,825 ⟶ 3,425:
smaAddValue(sma3,i);
writeln('100''000''000 insertions ',sma3.smaAverage:0:4);
end.</langsyntaxhighlight>
;output:
<pre>
Line 2,842 ⟶ 3,442:
 
real 0m0.780s { 64-Bit }</pre>
 
=={{header|Perl}}==
 
Using an initializer function which returns an anonymous closure which closes over an instance ''(separate for each call to the initializer!)'' of the lexical variables <code>$period</code>, <code>@list</code>, and <code>$sum</code>:
 
<langsyntaxhighlight lang="perl">sub sma_generator {
my $period = shift;
my (@list, $sum);
Line 2,863 ⟶ 3,464:
for (1, 2, 3, 2, 7) {
printf "append $_ --> sma = %.2f (with period 3)\n", $sma->($_);
}</langsyntaxhighlight>
 
{{out}}
Line 2,873 ⟶ 3,474:
append 7 --> sma = 4.00 (with period 3)
</pre>
 
=={{header|Perl 6}}==
<lang perl6>sub sma(Int \P where * > 0) returns Sub {
sub ($x) {
state @a = 0 xx P;
@a.push($x).shift;
P R/ [+] @a;
}
}</lang>
 
=={{header|Phix}}==
First create a separate file sma.e to encapsulate the private variables. Note in particular the complete lack of any special magic/syntax: it is just a table with some indexes.
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
sequence sma = {} -- {{period,history,circnxt}} (private to sma.e)
<span style="color: #004080;">sequence</span> <span style="color: #000000;">sma</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{}</span> <span style="color: #000080;font-style:italic;">-- ((period,history,circnxt)) (private to sma.e)</span>
integer sma_free = 0
<span style="color: #004080;">integer</span> <span style="color: #000000;">sma_free</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
 
global function new_sma(integer period)
<span style="color: #008080;">global</span> <span style="color: #008080;">function</span> <span style="color: #000000;">new_sma</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">period</span><span style="color: #0000FF;">)</span>
integer res
<span style="color: #004080;">integer</span> <span style="color: #000000;">res</span>
if sma_free then
<span style="color: #008080;">if</span> <span style="color: #000000;">sma_free</span> <span style="color: #008080;">then</span>
res = sma_free
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sma_free</span>
sma_free = sma[sma_free]
<span style="color: #000000;">sma_free</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sma</span><span style="color: #0000FF;">[</span><span style="color: #000000;">sma_free</span><span style="color: #0000FF;">]</span>
sma[res] = {period,{},0}
<span style="color: #000000;">sma</span><span style="color: #0000FF;">[</span><span style="color: #000000;">res</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">period</span><span style="color: #0000FF;">,{},</span><span style="color: #000000;">0</span><span style="color: #0000FF;">}</span>
else
<span style="color: #008080;">else</span>
sma = append(sma,{period,{},0})
<span style="color: #000000;">sma</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sma</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">period</span><span style="color: #0000FF;">,{},</span><span style="color: #000000;">0</span><span style="color: #0000FF;">})</span>
res = length(sma)
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sma</span><span style="color: #0000FF;">)</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return res
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
 
global procedure add_sma(integer sidx, atom val)
<span style="color: #008080;">global</span> <span style="color: #008080;">procedure</span> <span style="color: #000000;">add_sma</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">sidx</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">val</span><span style="color: #0000FF;">)</span>
integer period, circnxt
<span style="color: #004080;">integer</span> <span style="color: #000000;">period</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">circnxt</span>
sequence history
<span style="color: #004080;">sequence</span> <span style="color: #000000;">history</span>
{period,history,circnxt} = sma[sidx]
<span style="color: #0000FF;">{</span><span style="color: #000000;">period</span><span style="color: #0000FF;">,</span><span style="color: #000000;">history</span><span style="color: #0000FF;">,</span><span style="color: #000000;">circnxt</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sma</span><span style="color: #0000FF;">[</span><span style="color: #000000;">sidx</span><span style="color: #0000FF;">]</span>
sma[sidx][2] = 0 -- (kill refcount)
<span style="color: #000000;">sma</span><span style="color: #0000FF;">[</span><span style="color: #000000;">sidx</span><span style="color: #0000FF;">][</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span> <span style="color: #000080;font-style:italic;">-- (kill refcount)</span>
if length(history)<period then
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">history</span><span style="color: #0000FF;">)<</span><span style="color: #000000;">period</span> <span style="color: #008080;">then</span>
history = append(history,val)
<span style="color: #000000;">history</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">append</span><span style="color: #0000FF;">(</span><span style="color: #000000;">history</span><span style="color: #0000FF;">,</span><span style="color: #000000;">val</span><span style="color: #0000FF;">)</span>
else
<span style="color: #008080;">else</span>
circnxt += 1
<span style="color: #000000;">circnxt</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
if circnxt>period then
<span style="color: #008080;">if</span> <span style="color: #000000;">circnxt</span><span style="color: #0000FF;">></span><span style="color: #000000;">period</span> <span style="color: #008080;">then</span>
circnxt = 1
<span style="color: #000000;">circnxt</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
sma[sidx][3] = circnxt
<span style="color: #000000;">sma</span><span style="color: #0000FF;">[</span><span style="color: #000000;">sidx</span><span style="color: #0000FF;">][</span><span style="color: #000000;">3</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">circnxt</span>
history[circnxt] = val
<span style="color: #000000;">history</span><span style="color: #0000FF;">[</span><span style="color: #000000;">circnxt</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">val</span>
end if
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
sma[sidx][2] = history
<span style="color: #000000;">sma</span><span style="color: #0000FF;">[</span><span style="color: #000000;">sidx</span><span style="color: #0000FF;">][</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">history</span>
end procedure
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
 
global function get_sma_average(integer sidx)
<span style="color: #008080;">global</span> <span style="color: #008080;">function</span> <span style="color: #000000;">get_sma_average</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">sidx</span><span style="color: #0000FF;">)</span>
sequence history = sma[sidx][2]
<span style="color: #004080;">sequence</span> <span style="color: #000000;">history</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sma</span><span style="color: #0000FF;">[</span><span style="color: #000000;">sidx</span><span style="color: #0000FF;">][</span><span style="color: #000000;">2</span><span style="color: #0000FF;">]</span>
integer l = length(history)
<span style="color: #004080;">integer</span> <span style="color: #000000;">l</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">history</span><span style="color: #0000FF;">)</span>
if l=0 then return 0 end if
<span style="color: #008080;">if</span> <span style="color: #000000;">l</span><span style="color: #0000FF;">=</span><span style="color: #000000;">0</span> <span style="color: #008080;">then</span> <span style="color: #008080;">return</span> <span style="color: #000000;">0</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
return sum(history)/l
<span style="color: #008080;">return</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #000000;">history</span><span style="color: #0000FF;">)/</span><span style="color: #000000;">l</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
 
global function moving_average(integer sidx, atom val)
<span style="color: #008080;">global</span> <span style="color: #008080;">function</span> <span style="color: #000000;">moving_average</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">sidx</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">atom</span> <span style="color: #000000;">val</span><span style="color: #0000FF;">)</span>
add_sma(sidx,val)
<span style="color: #000000;">add_sma</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sidx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">val</span><span style="color: #0000FF;">)</span>
return get_sma_average(sidx)
<span style="color: #008080;">return</span> <span style="color: #000000;">get_sma_average</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sidx</span><span style="color: #0000FF;">)</span>
end function
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
 
global procedure free_sma(integer sidx)
<span style="color: #008080;">global</span> <span style="color: #008080;">procedure</span> <span style="color: #000000;">free_sma</span><span style="color: #0000FF;">(</span><span style="color: #004080;">integer</span> <span style="color: #000000;">sidx</span><span style="color: #0000FF;">)</span>
sma[sidx] = sma_free
<span style="color: #000000;">sma</span><span style="color: #0000FF;">[</span><span style="color: #000000;">sidx</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sma_free</span>
sma_free = sidx
<span style="color: #000000;">sma_free</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sidx</span>
end procedure</lang>
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
<!--</syntaxhighlight>-->
and the main file is:
<!--<syntaxhighlight lang="phix">(phixonline)-->
<lang Phix>include sma.e
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
 
<span style="color: #008080;">include</span> <span style="color: #000000;">sma</span><span style="color: #0000FF;">.</span><span style="color: #000000;">e</span>
constant sma3 = new_sma(3)
constant sma5 = new_sma(5)
<span style="color: #008080;">constant</span> <span style="color: #000000;">sma3</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">new_sma</span><span style="color: #0000FF;">(</span><span style="color: #000000;">3</span><span style="color: #0000FF;">)</span>
constant s = {1,2,3,4,5,5,4,3,2,1}
<span style="color: #008080;">constant</span> <span style="color: #000000;">sma5</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">new_sma</span><span style="color: #0000FF;">(</span><span style="color: #000000;">5</span><span style="color: #0000FF;">)</span>
integer si
<span style="color: #008080;">constant</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">4</span><span style="color: #0000FF;">,</span><span style="color: #000000;">3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">}</span>
 
<span style="color: #004080;">integer</span> <span style="color: #000000;">si</span>
for i=1 to length(s) do
si = s[i]
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
printf(1,"%2g: sma3=%8g, sma5=%8g\n",{si,moving_average(sma3,si),moving_average(sma5,si)})
<span style="color: #000000;">si</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
end for</lang>
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%2g: sma3=%8g, sma5=%8g\n"</span><span style="color: #0000FF;">,{</span><span style="color: #000000;">si</span><span style="color: #0000FF;">,</span><span style="color: #000000;">moving_average</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sma3</span><span style="color: #0000FF;">,</span><span style="color: #000000;">si</span><span style="color: #0000FF;">),</span><span style="color: #000000;">moving_average</span><span style="color: #0000FF;">(</span><span style="color: #000000;">sma5</span><span style="color: #0000FF;">,</span><span style="color: #000000;">si</span><span style="color: #0000FF;">)})</span>
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
<!--</syntaxhighlight>-->
{{out}}
<pre>
Line 2,961 ⟶ 3,558:
1: sma3= 2, sma5= 3
</pre>
 
=={{header|Picat}}==
<syntaxhighlight lang="picat">main =>
L=[1, 2, 3, 4, 5, 5, 4, 3, 2, 1],
Map3 = new_map([p=3]),
Map5 = new_map([p=5]),
foreach(N in L)
printf("n: %-2d sma3: %-17w sma5: %-17w\n",N, sma(N,Map3), sma(N,Map5))
end.
 
sma(N,Map) = Average =>
Stream = Map.get(stream,[]) ++ [N],
if Stream.len > Map.get(p) then
Stream := Stream.tail
end,
Average = cond(Stream.len == 0,
0,
sum(Stream) / Stream.len),
Map.put(stream,Stream).</syntaxhighlight>
 
{{out}}
<pre>n: 1 sma3: 1.0 sma5: 1.0
n: 2 sma3: 1.5 sma5: 1.5
n: 3 sma3: 2.0 sma5: 2.0
n: 4 sma3: 3.0 sma5: 2.5
n: 5 sma3: 4.0 sma5: 3.0
n: 5 sma3: 4.666666666666667 sma5: 3.8
n: 4 sma3: 4.666666666666667 sma5: 4.2
n: 3 sma3: 4.0 sma5: 4.2
n: 2 sma3: 3.0 sma5: 3.8
n: 1 sma3: 2.0 sma5: 3.0</pre>
 
 
=={{header|PicoLisp}}==
<langsyntaxhighlight PicoLisplang="picolisp">(de sma (@Len)
(curry (@Len (Data)) (N)
(push 'Data N)
(and (nth Data @Len) (con @)) # Truncate
(*/ (apply + Data) (length Data)) ) )</langsyntaxhighlight>
<langsyntaxhighlight PicoLisplang="picolisp">(def 'sma3 (sma 3))
(def 'sma5 (sma 5))
 
Line 2,978 ⟶ 3,607:
(format (sma3 N) *Scl)
" (sma5) "
(format (sma5 N) *Scl) ) )</langsyntaxhighlight>
{{out}}
<pre>1.00 (sma3) 1.00 (sma5) 1.00
Line 2,993 ⟶ 3,622:
=={{header|PL/I}}==
===version 1===
<langsyntaxhighlight lang="pli">SMA: procedure (N) returns (float byaddr);
declare N fixed;
declare A(*) fixed controlled,
Line 3,012 ⟶ 3,641:
A = 0;
p = 0;
end SMA;</langsyntaxhighlight>
===version 2===
{{trans|REXX}}
<langsyntaxhighlight lang="pli">*process source attributes xref;
mat: Proc Options(main);
Dcl a(10) Dec Fixed(8,6);
Line 3,059 ⟶ 3,688:
Return(s);
End;
End;</langsyntaxhighlight>
{{out}}
<pre> SMA with SMA with
Line 3,074 ⟶ 3,703:
9 3.000000 3.800000
10 2.000000 3.000000</pre>
 
=={{header|Pony}}==
<syntaxhighlight lang="pony">
class MovingAverage
let period: USize
let _arr: Array[I32] // circular buffer
var _curr: USize // index of pointer position
var _total: I32 // cache the total so far
 
new create(period': USize) =>
period = period'
_arr = Array[I32](period) // preallocate space
_curr = 0
_total = 0
 
fun ref apply(n: I32): F32 =>
_total = _total + n
if _arr.size() < period then
_arr.push(n)
else
try
let prev = _arr.update(_curr, n)?
_total = _total - prev
_curr = (_curr + 1) % period
end
end
_total.f32() / _arr.size().f32()
 
// ---- TESTING -----
actor Main
new create(env: Env) =>
let foo = MovingAverage(3)
let bar = MovingAverage(5)
let data: Array[I32] = [1; 2; 3; 4; 5; 5; 4; 3; 2; 1]
for v in data.values() do
env.out.print("Foo: " + foo(v).string())
end
for v in data.values() do
env.out.print("Bar: " + bar(v).string())
end
 
</syntaxhighlight>
 
=={{header|PowerShell}}==
<syntaxhighlight lang="powershell">
#This version allows a user to enter numbers one at a time to figure this into the SMA calculations
 
$inputs = @() #Create an array to hold all inputs as they are entered.
$period1 = 3 #Define the periods you want to utilize
$period2 = 5
 
Write-host "Enter numbers to observe their moving averages." -ForegroundColor Green
 
function getSMA ($inputs, [int]$period) #Function takes a array of entered values and a period (3 and 5 in this case)
{
if($inputs.Count -lt $period){$period = $inputs.Count} #Makes sure that if there's less numbers than the designated period (3 in this case), the number of availble values is used as the period instead.
for($count = 0; $count -lt $period; $count++) #Loop sums the latest available values
{
$result += $inputs[($inputs.Count) - $count - 1]
}
 
return ($result | ForEach-Object -begin {$sum=0 }-process {$sum+=$_} -end {$sum/$period}) #Gets the average for a given period
}
 
while($true) #Infinite loop so the user can keep entering numbers
{
try{$inputs += [decimal] (Read-Host)}catch{Write-Host "Enter only numbers" -ForegroundColor Red} #Enter the numbers. Error checking to help mitigate bad inputs (non-number values)
"Added " + $inputs[(($inputs.Count) - 1)] + ", sma($period1) = " + (getSMA $inputs $Period1) + ", sma($period2) = " + (getSMA $inputs $period2)
}
</syntaxhighlight>
 
=={{header|PureBasic}}==
<langsyntaxhighlight PureBasiclang="purebasic">Procedure.d SMA(Number, Period=0)
Static P
Static NewList L()
Line 3,094 ⟶ 3,795:
Next
ProcedureReturn sum/ListSize(L())
EndProcedure</langsyntaxhighlight>
 
=={{header|Python}}==
Line 3,100 ⟶ 3,801:
Both implementations use the [http://www.doughellmann.com/PyMOTW/collections/index.html deque] datatype.
===Procedural===
<langsyntaxhighlight lang="python">from collections import deque
 
def simplemovingaverage(period):
Line 3,116 ⟶ 3,817:
return summ / n
 
return sma</langsyntaxhighlight>
 
===Class based===
<langsyntaxhighlight lang="python">from collections import deque
 
class Simplemovingaverage():
Line 3,139 ⟶ 3,840:
average = sum( stream ) / streamlength
 
return average</langsyntaxhighlight>
 
'''Tests'''
<langsyntaxhighlight lang="python">if __name__ == '__main__':
for period in [3, 5]:
print ("\nSIMPLE MOVING AVERAGE (procedural): PERIOD =", period)
Line 3,156 ⟶ 3,857:
print (" Next number = %-2g, SMA = %g " % (i, sma(i)))
for i in range(5, 0, -1):
print (" Next number = %-2g, SMA = %g " % (i, sma(i)))</langsyntaxhighlight>
 
{{out}}
Line 3,206 ⟶ 3,907:
Next number = 2 , SMA = 3.8
Next number = 1 , SMA = 3 </pre>
 
=={{header|Quackery}}==
 
<syntaxhighlight lang="quackery"> [ $ "bigrat.qky" loadfile ] now!
 
[ over size -
space swap of
join ] is pad ( $ n --> $ )
 
[ ' [ stack [ ] ]
copy nested
' [ tuck take swap join
dup size ] join
swap join
' [ > if
[ 1 split nip ]
tuck swap put
0 over witheach +
swap size
dip n->v n->v v/ ]
join copy ] is make-sma ( n --> [ )
( behaviour of [ is: n --> n/d )
 
[ stack ] is sma-3 ( --> s )
3 make-sma sma-3 put
 
[ stack ] is sma-5 ( --> s )
5 make-sma sma-5 put
 
say "n sma-3 sma-5" cr cr
' [ 1 2 3 4 5 5 4 3 2 1 ]
witheach
[ dup echo sp
dup sma-3 share do
7 point$ 10 pad echo$ sp
sma-5 share do
7 point$ 10 pad echo$ cr ]
</syntaxhighlight>
 
{{out}}
 
<pre>n sma-3 sma-5
 
1 1 1
2 1.5 1.5
3 2 2
4 3 2.5
5 4 3
5 4.6666667 3.8
4 4.6666667 4.2
3 4 4.2
2 3 3.8
1 2 3
</pre>
 
=={{header|R}}==
This is easiest done with two functions: one to handle the state (i.e. the numbers already entered), and one to calculate the average.
<langsyntaxhighlight Rlang="r">#concat concatenates the new values to the existing vector of values, then discards any values that are too old.
lastvalues <- local(
{
Line 3,239 ⟶ 3,994:
moving.average(-3) # 1
moving.average(8) # 2
moving.average(7) # 4</langsyntaxhighlight>
 
=={{header|Racket}}==
<langsyntaxhighlight Racketlang="racket">#lang racket
 
(require data/queue)
Line 3,263 ⟶ 4,018:
([i '(1 2 3 4 5 5 4 3 2 1)])
(values (sma3 i) (sma5 i)))
</syntaxhighlight>
</lang>
 
=={{header|Raku}}==
(formerly Perl 6)
 
{{works with|Rakudo|2016.08}}
<syntaxhighlight lang="raku" line>sub sma-generator (Int $P where * > 0) {
sub ($x) {
state @a = 0 xx $P;
@a.push($x).shift;
@a.sum / $P;
}
}
 
# Usage:
my &sma = sma-generator 3;
 
for 1, 2, 3, 2, 7 {
printf "append $_ --> sma = %.2f (with period 3)\n", sma $_;
}</syntaxhighlight>
 
{{out}}
<pre>
append 1 --> sma = 0.33 (with period 3)
append 2 --> sma = 1.00 (with period 3)
append 3 --> sma = 2.00 (with period 3)
append 2 --> sma = 2.33 (with period 3)
append 7 --> sma = 4.00 (with period 3)
</pre>
 
=={{header|REXX}}==
The same item list of numbers was used as forin the &nbsp; '''ALGOL68''' &nbsp; example.
<lang rexx>/*REXX program illustrates simple moving average using a constructed list. */
parse arg p q n . /*get optional arguments from the C.L. */
if p=='' then p=3 /*the 1st period (the default is: 3).*/
if q=='' then q=5 /* " 2nd " " " " 5).*/
if n=='' then n=10 /*the number of items in the list. */
@.=0 /*define array with initial zero values*/
/* [↓] build 1st half of list*/
do j=1 for n%2; @.j=j; end /* ··· increasing values.*/
/* [↓] build 2nd half of list*/
do k=n%2 to 1 by -1; @.j=k; j=j+1; end /* ··· decreasing values.*/
 
The 1<sup>st</sup> and 2<sup>nd</sup> periods (number of values) were parametrized, &nbsp; as well as the total number of values.
say ' ' " SMA with " ' SMA with '
<syntaxhighlight lang="rexx">/*REXX program illustrates and displays a simple moving average using a constructed list*/
say ' number ' " period" p' ' ' period' q
parse arg p q n . /*obtain optional arguments from the CL*/
say ' ──────── ' "──────────" '──────────'
if p=='' | p=="," then p= 3 /*Not specified? Then use the default.*/
if q=='' | q=="," then q= 5 /* " " " " " " */
if n=='' | n=="," then n= 10 /* " " " " " " */
@.= 0 /*default value, only needed for odd N.*/
do j=1 for n%2; @.j= j /*build 1st half of list, increasing #s*/
end /*j*/
 
do k=n%2 by -1 to 1; @.j= k; j= j+1 /* " 2nd " " " /* [↓] perform a simpledecreasing moving" average*/
end do m=1 for n/*k*/
say center(@.m,' 10) number ' left(sma( " SMA with period" p,m),' 11)' " SMA with left(sma(q,m),period" 11)q
say ' ──────── ' "───────────────────" '───────────────────'
end /*m*/ /* [↑] show a simple moving average.*/
exit /*stick a fork in it, we pad='re all done. */ '
do m=1 for n; say center(@.m, 10) pad left(SMA(p, m), 19) left(SMA(q, m), 19)
/*────────────────────────────────────────────────────────────────────────────*/
end /*m*/
sma: procedure expose @.; parse arg p,j; s=0; i=0
exit do k=max(1,j-p+1) to j+p for p while k<=j; i=i+1 /*stick a fork in it, we're all done. */
/*──────────────────────────────────────────────────────────────────────────────────────*/
s=s+@.k
SMA: procedure expose @.; parse arg p,j; end /*k*/ i= 0 ; $= 0
do k=max(1, j-p+1) to j+p for p while k<=j; i= i + 1; $= $ + @.k
return s/i</lang>
end /*k*/
'''output''' &nbsp; using the generated default list of numbers:
return $/i /*SMA ≡ simple moving average. */</syntaxhighlight>
{{out|output|text=&nbsp; when using the generated default input numbers:}}
<pre>
number SMA with period 3 SMA with period SMA with5
──────── ─────────────────── ───────────────────
number period 3 period 5
1 1 1
──────── ────────── ──────────
12 1.5 1.5
3 2 1.5 1.5 2
4 3 2 2.5
5 4 3 2.5 3
5 4 4.66666667 3.8
54 4.66666667 3 4.82
43 4.66666667 4.2
2 3 4 4 3.28
1 2 3 3.8
1 2 3
</pre>
 
=={{header|Ring}}==
===version 1===
<syntaxhighlight lang="ring">
load "stdlib.ring"
decimals(8)
maxperiod = 20
nums = newlist(maxperiod,maxperiod)
accum = list(maxperiod)
index = list(maxperiod)
window = list(maxperiod)
for i = 1 to maxperiod
index[i] = 1
accum[i] = 0
window[i] = 0
next
for i = 1 to maxperiod
for j = 1 to maxperiod
nums[i][j] = 0
next
next
for n = 1 to 5
see "number = " + n + " sma3 = " + left((string(sma(n,3)) + " "),9) + " sma5 = " + sma(n,5) + nl
next
for n = 5 to 1 step -1
see "number = " + n + " sma3 = " + left((string(sma(n,3)) + " "),9) + " sma5 = " + sma(n,5) + nl
next
see nl
func sma number, period
accum[period] += number - nums[period][index[period]]
nums[period][index[period]] = number
index[period]= (index[period] + 1) % period + 1
if window[period]<period window[period] += 1 ok
return (accum[period] / window[period])
</syntaxhighlight>
Output:
<pre>
number = 1 sma3 = 1 sma5 = 1
number = 2 sma3 = 1.5000000 sma5 = 1.50000000
number = 3 sma3 = 2 sma5 = 2
number = 4 sma3 = 3 sma5 = 2.50000000
number = 5 sma3 = 4 sma5 = 3
number = 5 sma3 = 4.6666666 sma5 = 3.80000000
number = 4 sma3 = 4.6666666 sma5 = 4.20000000
number = 3 sma3 = 4 sma5 = 4.20000000
number = 2 sma3 = 3 sma5 = 3.80000000
number = 1 sma3 = 2 sma5 = 3
</pre>
 
===version 2===
<syntaxhighlight lang="ring">
load "stdlib.ring"
decimals(8)
maxperiod = 20
nums = newlist(maxperiod,maxperiod)
accum = list(maxperiod)
index = list(maxperiod)
window = list(maxperiod)
for i = 1 to maxperiod
index[i] = 1
accum[i] = 0
window[i] = 0
next
for i = 1 to maxperiod
for j = 1 to maxperiod
nums[i][j] = 0
next
next
for n = 1 to 5
see "number = " + n + " sma3 = " + left((string(sma(n,3)) + " "),9) + " sma5 = " + sma(n,5) + nl
next
for n = 5 to 1 step -1
see "number = " + n + " sma3 = " + left((string(sma(n,3)) + " "),9) + " sma5 = " + sma(n,5) + nl
next
see nl
func sma number, period
accum[period] += number - nums[period][index[period]]
nums[period][index[period]] = number
index[period]= (index[period] + 1) % period + 1
if window[period]<period window[period] += 1 ok
return (accum[period] / window[period])
</syntaxhighlight>
Output:
<pre>
number = 1 sma3 = 1 sma5 = 1
number = 2 sma3 = 1.5000000 sma5 = 1.50000000
number = 3 sma3 = 2 sma5 = 2
number = 4 sma3 = 3 sma5 = 2.50000000
number = 5 sma3 = 4 sma5 = 3
number = 5 sma3 = 4.6666666 sma5 = 3.80000000
number = 4 sma3 = 4.6666666 sma5 = 4.20000000
number = 3 sma3 = 4 sma5 = 4.20000000
number = 2 sma3 = 3 sma5 = 3.80000000
number = 1 sma3 = 2 sma5 = 3
</pre>
 
===version 3===
<syntaxhighlight lang="ring">
 
### RING: Function Moving Average. Bert Mariani 2016-06-22
 
###------------------------------
### Data array of Google prices
 
aGOOGPrices = ["658","675","670","664","664","663","663","662","675","693","689","675",
"636","633","632","607","607","617","617","581","593","570","574","571","575","596",
"596","601","583","635","587","574","552","531","536","502","488","482","490","503",
"507","521","534","525","534","559","552","554","555","555","552","579","580","577",
"575","562","560","559","558","569","573","577","574","559","552","553","560","569",
"582","579","593","598","593","598","593","586","602","591","594","595","603","614",
"620","625","635","627","632","631","620","626","616","606","602","659","683","671",
"670","659","673","679"]
 
###-------------------------------------------------------------
### CALL the Function: MovingAverage arrayOfPrices timePeriod
 
aGOOGMvgAvg = MovingAverage( aGOOGPrices, 10 )
 
aGOOGMvgAvg = MovingAverage( aGOOGPrices, 30 )
 
###-------------------------------------------------------------
### FUNCTION: MovingAverage
 
Func MovingAverage arrayPrices, timePeriod
 
arrayMvgAvg = [] ### Output Results to this array
z = len(arrayPrices) ### array data length
sumPrices = 0
###--------------------------------
### First MAvg Sum 1 to timePeriod
###--------------------------------
for i = 1 to timePeriod
sumPrices = sumPrices + arrayPrices[i]
mvgAvg = sumPrices / i
Add( arrayMvgAvg, mvgAvg)
next
###-----------------------------------------------
### Second MAvg Sum timePeriod +1 to End of Data
###-----------------------------------------------
for i = timePeriod + 1 to z
sumPrices = sumPrices - arrayPrices[i-timePeriod] + arrayPrices[i]
mvgAvg = sumPrices / timePeriod
Add (arrayMvgAvg, mvgAvg
next
return arrayMvgAvg
 
###-------------------------------------------------------------
OUTPUT Google Prices moving average using timePeriod = 10
 
Index 88 CurPrice 631 Sum 17735 MvgAvg 591.17
Index 89 CurPrice 620 Sum 17797 MvgAvg 593.23
Index 90 CurPrice 626 Sum 17854 MvgAvg 595.13
Index 91 CurPrice 616 Sum 17897 MvgAvg 596.57
Index 92 CurPrice 606 Sum 17926 MvgAvg 597.53
Index 93 CurPrice 602 Sum 17954 MvgAvg 598.47
Index 94 CurPrice 659 Sum 18054 MvgAvg 601.80
Index 95 CurPrice 683 Sum 18185 MvgAvg 606.17
Index 96 CurPrice 671 Sum 18303 MvgAvg 610.10
Index 97 CurPrice 670 Sum 18413 MvgAvg 613.77
Index 98 CurPrice 659 Sum 18503 MvgAvg 616.77
Index 99 CurPrice 673 Sum 18594 MvgAvg 619.80
Index 100 CurPrice 679 Sum 18694 MvgAvg 623.13
###-------------------------------------------------------------
 
</syntaxhighlight>
 
=={{header|Ruby}}==
A closure:
<langsyntaxhighlight lang="ruby">def simple_moving_average(size)
nums = []
sum = 0.0
Line 3,329 ⟶ 4,281:
printf "Next number = %d, SMA_3 = %.3f, SMA_5 = %.1f\n",
num, ma3.call(num), ma5.call(num)
end</langsyntaxhighlight>
 
A class
<langsyntaxhighlight lang="ruby">class MovingAverager
def initialize(size)
@size = size
Line 3,359 ⟶ 4,311:
printf "Next number = %d, SMA_3 = %.3f, SMA_5 = %.1f\n",
num, ma3 << num, ma5 <<num
end</langsyntaxhighlight>
 
=={{header|Run Basic}}==
<langsyntaxhighlight lang="runbasic">data 1,2,3,4,5,5,4,3,2,1
dim sd(10) ' series data
global sd ' make it global so we all see it
Line 3,379 ⟶ 4,332:
print sd(i);" sma:";p;" ";sumSd / p1
next i
end function</langsyntaxhighlight>
<pre>----- SMA:3 -----
1 sma:3 1
Line 3,402 ⟶ 4,355:
2 sma:5 3.79999995
1 sma:5 3</pre>
 
=={{header|Rust}}==
===Vector Based===
<syntaxhighlight lang="rust">struct SimpleMovingAverage {
period: usize,
numbers: Vec<usize>
}
 
impl SimpleMovingAverage {
fn new(p: usize) -> SimpleMovingAverage {
SimpleMovingAverage {
period: p,
numbers: Vec::new()
}
}
 
fn add_number(&mut self, number: usize) -> f64 {
self.numbers.push(number);
if self.numbers.len() > self.period {
self.numbers.remove(0);
}
if self.numbers.is_empty() {
return 0f64;
}else {
let sum = self.numbers.iter().fold(0, |acc, x| acc+x);
return sum as f64 / self.numbers.len() as f64;
}
}
}
 
fn main() {
for period in [3, 5].iter() {
println!("Moving average with period {}", period);
 
let mut sma = SimpleMovingAverage::new(*period);
for i in [1, 2, 3, 4, 5, 5, 4, 3, 2, 1].iter() {
println!("Number: {} | Average: {}", i, sma.add_number(*i));
}
}
}</syntaxhighlight>
 
===Double-ended Queue Based===
<syntaxhighlight lang="rust">use std::collections::VecDeque;
 
struct SimpleMovingAverage {
period: usize,
numbers: VecDeque<usize>
}
 
impl SimpleMovingAverage {
fn new(p: usize) -> SimpleMovingAverage {
SimpleMovingAverage {
period: p,
numbers: VecDeque::new()
}
}
 
fn add_number(&mut self, number: usize) -> f64 {
self.numbers.push_back(number);
if self.numbers.len() > self.period {
self.numbers.pop_front();
}
if self.numbers.is_empty() {
return 0f64;
}else {
let sum = self.numbers.iter().fold(0, |acc, x| acc+x);
return sum as f64 / self.numbers.len() as f64;
}
}
}
 
fn main() {
for period in [3, 5].iter() {
println!("Moving average with period {}", period);
 
let mut sma = SimpleMovingAverage::new(*period);
for i in [1, 2, 3, 4, 5, 5, 4, 3, 2, 1].iter() {
println!("Number: {} | Average: {}", i, sma.add_number(*i));
}
}
}</syntaxhighlight>
 
<pre>Moving average with period 3
Number: 1 | Average: 1
Number: 2 | Average: 1.5
Number: 3 | Average: 2
Number: 4 | Average: 3
Number: 5 | Average: 4
Number: 5 | Average: 4.666666666666667
Number: 4 | Average: 4.666666666666667
Number: 3 | Average: 4
Number: 2 | Average: 3
Number: 1 | Average: 2
Moving average with period 5
Number: 1 | Average: 1
Number: 2 | Average: 1.5
Number: 3 | Average: 2
Number: 4 | Average: 2.5
Number: 5 | Average: 3
Number: 5 | Average: 3.8
Number: 4 | Average: 4.2
Number: 3 | Average: 4.2
Number: 2 | Average: 3.8
Number: 1 | Average: 3
</pre>
 
=={{header|Scala}}==
<langsyntaxhighlight lang="scala">class MovingAverage(period: Int) {
private var queue = new scala.collection.mutable.Queue[Double]()
def apply(n: Double) = {
Line 3,414 ⟶ 4,476:
override def toString = queue.mkString("(", ", ", ")")+", period "+period+", average "+(queue.sum / queue.size)
def clear = queue.clear
}</langsyntaxhighlight>
 
<pre>
Line 3,452 ⟶ 4,514:
 
=={{header|Scheme}}==
<langsyntaxhighlight lang="scheme">(define ((simple-moving-averager size . nums) num)
(set! nums (cons num (if (= (length nums) size) (reverse (cdr (reverse nums))) nums)))
(/ (apply + nums) (length nums)))
Line 3,458 ⟶ 4,520:
(define av (simple-moving-averager 3))
(map av '(1 2 3 4 5 5 4 3 2 1))
</syntaxhighlight>
</lang>
{{out}}
<pre>
(1 3/2 2 3 4 14/3 14/3 4 3 2)
</pre>
 
 
=={{header|Sidef}}==
Implemented with closures:
<langsyntaxhighlight lang="ruby">func simple_moving_average(period) {
 
var list = [];
var sum = 0;
 
func (number) {
list.append(number);
sum += number;
if (list.len > period) && ({
sum -= list.shift;
);}
return (sum / list.length);
}
}
 
var ma3 = simple_moving_average(3);
var ma5 = simple_moving_average(5);
 
[for num (1 ..^ 5)..., flip( 5 ^1.. 1 5))...].reverse -> each {|num|
printf("Next number =  %d, SMA_3 =  %.3f, SMA_5 =  %.1f\n",
num, ma3.call(num), ma5.call(num));
}</langsyntaxhighlight>
 
Implemented as a class:
<langsyntaxhighlight lang="ruby">class sma_generator(period, list=[], sum=0) {
 
method SMA(number) {
list.append(number);
sum += number;
if (list.len > period) && ({
sum -= list.shift;
);}
return (sum / list.len);
}
}
 
var ma3 = sma_generator(3);
var ma5 = sma_generator(5);
 
[for num (1 ..^ 5)..., flip( 5 ^1.. 1 5))...].reverse -> each {|num|
printf("Next number =  %d, SMA_3 =  %.3f, SMA_5 =  %.1f\n",
num, ma3.SMA(num), ma5.SMA(num));
}</langsyntaxhighlight>
 
{{out}}
Line 3,528 ⟶ 4,589:
{{works with|GNU Smalltalk}}
 
<langsyntaxhighlight lang="smalltalk">Object subclass: MovingAverage [
|valueCollection period collectedNumber sum|
MovingAverage class >> newWithPeriod: thePeriod [
Line 3,558 ⟶ 4,619:
^ self sma
]
].</langsyntaxhighlight>
 
<langsyntaxhighlight lang="smalltalk">|sma3 sma5|
 
sma3 := MovingAverage newWithPeriod: 3.
Line 3,569 ⟶ 4,630:
v . (sma3 add: v) asFloat . (sma5 add: v) asFloat
}) displayNl
]</langsyntaxhighlight>
 
=={{header|Swift}}==
 
{{trans|Rust}}
 
<syntaxhighlight lang="swift">struct SimpleMovingAverage {
var period: Int
var numbers = [Double]()
 
mutating func addNumber(_ n: Double) -> Double {
numbers.append(n)
 
if numbers.count > period {
numbers.removeFirst()
}
 
guard !numbers.isEmpty else {
return 0
}
 
return numbers.reduce(0, +) / Double(numbers.count)
}
}
 
for period in [3, 5] {
print("Moving average with period \(period)")
 
var averager = SimpleMovingAverage(period: period)
 
for n in [1.0, 2, 3, 4, 5, 5, 4, 3, 2, 1] {
print("n: \(n); average \(averager.addNumber(n))")
}
}</syntaxhighlight>
 
{{out}}
 
<pre style="overflow: scroll; height: 25em">Moving average with period 3
n: 1.0; average 1.0
n: 2.0; average 1.5
n: 3.0; average 2.0
n: 4.0; average 3.0
n: 5.0; average 4.0
n: 5.0; average 4.666666666666667
n: 4.0; average 4.666666666666667
n: 3.0; average 4.0
n: 2.0; average 3.0
n: 1.0; average 2.0
Moving average with period 5
n: 1.0; average 1.0
n: 2.0; average 1.5
n: 3.0; average 2.0
n: 4.0; average 2.5
n: 5.0; average 3.0
n: 5.0; average 3.8
n: 4.0; average 4.2
n: 3.0; average 4.2
n: 2.0; average 3.8
n: 1.0; average 3.0</pre>
 
=={{header|Tcl}}==
{{works with|Tcl|8.6}} or {{libheader|TclOO}}
<langsyntaxhighlight lang="tcl">oo::class create SimpleMovingAverage {
variable vals idx
constructor {{period 3}} {
Line 3,583 ⟶ 4,702:
expr {[tcl::mathop::+ {*}$vals]/double([llength $vals])}
}
}</langsyntaxhighlight>
Demonstration:
<langsyntaxhighlight lang="tcl">SimpleMovingAverage create averager3
SimpleMovingAverage create averager5 5
foreach n {1 2 3 4 5 5 4 3 2 1} {
puts "Next number = $n, SMA_3 = [averager3 val $n], SMA_5 = [averager5 val $n]"
}</langsyntaxhighlight>
{{out}}
<pre>Next number = 1, SMA_3 = 1.0, SMA_5 = 1.0
Line 3,608 ⟶ 4,727:
Press <tt>ON</tt> to terminate the program.
 
<langsyntaxhighlight lang="ti83b">:1->C
:While 1
:Prompt I
Line 3,615 ⟶ 4,734:
:Disp mean(L1)
:1+C->C
:End</langsyntaxhighlight>
 
=={{header|TI-89 BASIC}}==
Line 3,621 ⟶ 4,740:
 
Function that returns a list containing the averaged data of the supplied argument
<langsyntaxhighlight lang="ti89b">movinavg(list,p)
Func
Local r, i, z
Line 3,632 ⟶ 4,751:
EndFunc
 
</syntaxhighlight>
</lang>
 
Program that returns a simple value at each invocation:
<langsyntaxhighlight lang="ti89b">movinav2(x_,v_)
Prgm
If getType(x_)="STR" Then
Line 3,646 ⟶ 4,765:
sum(list)/dim(list)→#v_
EndPrgm
</syntaxhighlight>
</lang>
 
Example1: Using the function<br>
Line 3,679 ⟶ 4,798:
sum(...)/(i-z) → r[i] will average them and store the result in the appropriate place in the result list<br>
 
=={{header|zklVBA}}==
This is a "simple" moving average.
<lang zkl>class [static] SMA{var P=3,ns=L(); // only one instance of this class
<syntaxhighlight lang="vb">Class sma
fcn init(n){
'to be stored in a class module with name "sma"
if(P<ns.append(n.toFloat()).len()) ns.del(0);
Private n As Integer 'period
returnClass(ns.sum(0.0)/ns.len()); // return average, not Class
Private arr() As Double 'circular list
}
Private index As Integer 'pointer into arr
fcn reset(p){P=p;ns=L();} // to make examples easier
Private oldsma As Double
}</lang>
<lang zkl>zkl: T(1,2,3,4,5,5,4,3,2,1).apply(SMA)
L(1,1.5,2,3,4,4.66667,4.66667,4,3,2)
 
Public Sub init(size As Integer)
zkl: SMA.reset(5)
n = size
zkl: T(1,2,3,4,5,5,4,3,2,1).apply(SMA)
ReDim arr(n - 1)
L(1,1.5,2,2.5,3,3.8,4.2,4.2,3.8,3)</lang>
index = 0
Using a closure and creating a function
End Sub
<lang zkl>fcn SMA(P){
fcn(n,ns,P){ if(P<ns.append(n.toFloat()).len()) ns.del(0);
ns.sum(0.0)/ns.len()
}.fp1(L(),P)
}</lang>
<lang zkl>zkl: T(1,2,3,4,5,5,4,3,2,1).apply(SMA(3))
L(1,1.5,2,3,4,4.66667,4.66667,4,3,2)
 
Public Function sma(number As Double) As Double
zkl: T(1,2,3,4,5,5,4,3,2,1).apply(SMA(5))
sma = oldsma + (-arr(index) + number) / n
L(1,1.5,2,2.5,3,3.8,4.2,4.2,3.8,3)</lang>
oldsma = sma
arr(index) = number
index = (index + 1) Mod n
End Function
 
Normal module
Public Sub main()
s = [{1,2,3,4,5,5,4,3,2,1}]
Dim sma3 As New sma
Dim sma5 As New sma
sma3.init 3
sma5.init 5
For i = 1 To UBound(s)
Debug.Print i, Format(sma3.sma(CDbl(s(i))), "0.00000"),
Debug.Print Format(sma5.sma(CDbl(s(i))), "0.00000")
Next i
End Sub</syntaxhighlight>{{out}}
<pre> 1 0,33333 0,20000
2 1,00000 0,60000
3 2,00000 1,20000
4 3,00000 2,00000
5 4,00000 3,00000
6 4,66667 3,80000
7 4,66667 4,20000
8 4,00000 4,20000
9 3,00000 3,80000
10 2,00000 3,00000</pre>
 
=={{header|VBScript}}==
<syntaxhighlight lang="vb">data = "1,2,3,4,5,5,4,3,2,1"
token = Split(data,",")
stream = ""
WScript.StdOut.WriteLine "Number" & vbTab & "SMA3" & vbTab & "SMA5"
For j = LBound(token) To UBound(token)
If Len(stream) = 0 Then
stream = token(j)
Else
stream = stream & "," & token(j)
End If
WScript.StdOut.WriteLine token(j) & vbTab & Round(SMA(stream,3),2) & vbTab & Round(SMA(stream,5),2)
Next
 
Function SMA(s,p)
If Len(s) = 0 Then
SMA = 0
Exit Function
End If
d = Split(s,",")
sum = 0
If UBound(d) + 1 >= p Then
c = 0
For i = UBound(d) To LBound(d) Step -1
sum = sum + Int(d(i))
c = c + 1
If c = p Then
Exit For
End If
Next
SMA = sum / p
Else
For i = UBound(d) To LBound(d) Step -1
sum = sum + Int(d(i))
Next
SMA = sum / (UBound(d) + 1)
End If
End Function</syntaxhighlight>
 
{{Out}}
<pre>
Number SMA3 SMA5
1 1 1
2 1.5 1.5
3 2 2
4 3 2.5
5 4 3
5 4.67 3.8
4 4.67 4.2
3 4 4.2
2 3 3.8
1 2 3
</pre>
 
=={{header|V (Vlang)}}==
{{trans|Go}}
<syntaxhighlight lang="v (vlang)">fn sma(period int) fn(f64) f64 {
mut i := int(0)
mut sum := f64(0)
mut storage := []f64{len: 0, cap:period}
return fn[mut storage, mut sum, mut i, period](input f64) f64 {
if storage.len < period {
sum += input
storage << input
}
sum += input - storage[i]
storage[i], i = input, (i+1)%period
return sum / f64(storage.len)
}
}
fn main() {
sma3 := sma(3)
sma5 := sma(5)
println("x sma3 sma5")
for x in [f64(1), 2, 3, 4, 5, 5, 4, 3, 2, 1] {
println("${x:5.3f} ${sma3(x):5.3f} ${sma5(x):5.3f}")
}
}</syntaxhighlight>
 
{{out}}
<pre>
x sma3 sma5
1.000 1.000 1.000
2.000 1.500 1.500
3.000 2.000 2.000
4.000 3.000 2.500
5.000 4.000 3.000
5.000 4.667 3.800
4.000 4.667 4.200
3.000 4.000 4.200
2.000 3.000 3.800
1.000 2.000 3.000
</pre>
 
=={{header|Wren}}==
{{trans|Go}}
{{libheader|Wren-fmt}}
<syntaxhighlight lang="wren">import "./fmt" for Fmt
 
var sma = Fn.new { |period|
var i = 0
var sum = 0
var storage = []
return Fn.new { |input|
if (storage.count < period) {
sum = sum + input
storage.add(input)
}
sum = sum + input - storage[i]
storage[i] = input
i = (i+1) % period
return sum/storage.count
}
}
 
var sma3 = sma.call(3)
var sma5 = sma.call(5)
System.print(" x sma3 sma5")
for (x in [1, 2, 3, 4, 5, 5, 4, 3, 2, 1]) {
Fmt.precision = 3
Fmt.print("$5f $5f $5f", x, sma3.call(x), sma5.call(x))
}</syntaxhighlight>
 
{{out}}
<pre>
x sma3 sma5
1.000 1.000 1.000
2.000 1.500 1.500
3.000 2.000 2.000
4.000 3.000 2.500
5.000 4.000 3.000
5.000 4.667 3.800
4.000 4.667 4.200
3.000 4.000 4.200
2.000 3.000 3.800
1.000 2.000 3.000
</pre>
 
=={{header|zkl}}==
<syntaxhighlight lang="zkl">fcn SMA(P){
fcn(n,ns,P){
sz:=ns.append(n.toFloat()).len();
if(P>sz) return(0.0);
if(P<sz) ns.del(0);
ns.sum(0.0)/P;
}.fp1(List.createLong(P+1),P) // pre-allocate a list of length P+1
}</syntaxhighlight>
fp1 creates a partial application fixing the (in this case) the second and third
parameters
<syntaxhighlight lang="zkl">T(1,2,3,4,5,5,4,3,2,1).apply(SMA(3)).println();
T(1,2,3,4,5,5,4,3,2,1).apply(SMA(5)).println();</syntaxhighlight>
{{out}}
<pre>
L(0,0,2,3,4,4.66667,4.66667,4,3,2)
L(0,0,0,0,3,3.8,4.2,4.2,3.8,3)
</pre>
2,458

edits