Data commit
This commit is contained in:
parent
7387c8f97b
commit
cb5bb5e222
199093 changed files with 3378972 additions and 0 deletions
3
Task/Averages-Simple-moving-average/00-META.yaml
Normal file
3
Task/Averages-Simple-moving-average/00-META.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/Averages/Simple_moving_average
|
||||
note: Probability and statistics
|
||||
43
Task/Averages-Simple-moving-average/00-TASK.txt
Normal file
43
Task/Averages-Simple-moving-average/00-TASK.txt
Normal file
|
|
@ -0,0 +1,43 @@
|
|||
Computing the [[wp:Moving_average#Simple_moving_average|simple moving average]] of a series of numbers.
|
||||
|
||||
;Task
|
||||
|
||||
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.
|
||||
|
||||
{{task heading|Description}}
|
||||
|
||||
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().
|
||||
|
||||
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.
|
||||
|
||||
<br>
|
||||
''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.
|
||||
|
||||
Pseudo-code for an implementation of SMA is:
|
||||
<pre>
|
||||
function SMA(number: N):
|
||||
stateful integer: P
|
||||
stateful list: stream
|
||||
number: average
|
||||
|
||||
stream.append_last(N)
|
||||
if stream.length() > P:
|
||||
# Only average the last P elements of the stream
|
||||
stream.delete_first()
|
||||
if stream.length() == 0:
|
||||
average = 0
|
||||
else:
|
||||
average = sum( stream.values() ) / stream.length()
|
||||
return average
|
||||
</pre>
|
||||
|
||||
{{task heading|See also}}
|
||||
|
||||
{{Related tasks/Statistical measures}}
|
||||
|
||||
<hr>
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
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)))
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
* Averages/Simple moving average 26/08/2015
|
||||
AVGSMA CSECT
|
||||
USING AVGSMA,R12
|
||||
LR R12,R15
|
||||
ST R14,SAVER14
|
||||
ZAP II,=P'0' ii=0
|
||||
LA R7,1
|
||||
LH R3,NA
|
||||
SRA R3,1 na/2
|
||||
LOOPA CR R7,R3 do i=1 to na/2
|
||||
BH ELOOPA
|
||||
AP II,=P'1000' ii=ii+1000
|
||||
LR R1,R7 i
|
||||
MH R1,=H'6'
|
||||
LA R4,A-6(R1)
|
||||
MVC 0(6,R4),II a(i)=ii
|
||||
LH R1,NA na
|
||||
SR R1,R7 -i
|
||||
MH R1,=H'6'
|
||||
LA R4,A(R1)
|
||||
MVC 0(6,R4),II a(na+1-i)=ii
|
||||
LA R7,1(R7)
|
||||
B LOOPA
|
||||
ELOOPA XPRNT =CL30' n sma3 sma5 ',30
|
||||
XPRNT =CL30' ----- ----------- -----------',30
|
||||
LA R7,1 i=1
|
||||
LOOP CH R7,NA do i=1 to na
|
||||
BH RETURN
|
||||
STH R7,N n=i
|
||||
XDECO R7,C i
|
||||
MVC BUF+1(5),C+7
|
||||
MVC P,=H'3' p=3
|
||||
BAL R14,SMA
|
||||
MVC C(13),EDMASK
|
||||
ED C(13),SS sma(3,i)
|
||||
MVC BUF+7(11),C+2
|
||||
MVC P,=H'5' p=5
|
||||
BAL R14,SMA
|
||||
MVC C(13),EDMASK
|
||||
ED C(13),SS sma(5,i)
|
||||
MVC BUF+19(11),C+2
|
||||
XPRNT BUF,30 output i,sma3,sma5
|
||||
LA R7,1(R7)
|
||||
B LOOP
|
||||
* ***** sub sma(p,n) returns(PL6)
|
||||
SMA LH R5,N
|
||||
SH R5,P
|
||||
A R5,=F'1' ia=n-p+1
|
||||
C R5,=F'1'
|
||||
BH OKIA
|
||||
LA R5,1 ia=1
|
||||
OKIA LH R6,NA ib=na
|
||||
CH R6,N
|
||||
BL OKIB
|
||||
LH R6,N ib=n
|
||||
OKIB ZAP II,=P'0' ii=0
|
||||
ZAP SS,=P'0' ss=0
|
||||
LR R3,R5 k=ia
|
||||
LOOPK CR R3,R6 do k=ia to ib
|
||||
BH ELOOPK
|
||||
AP II,=P'1' ii=ii+1
|
||||
LR R1,R3
|
||||
MH R1,=H'6'
|
||||
LA R4,A-6(R1)
|
||||
MVC C(6),0(R4) ss=ss+a(k)
|
||||
AP SS,C(6)
|
||||
LA R3,1(R3)
|
||||
B LOOPK
|
||||
ELOOPK ZAP C,SS
|
||||
DP C,II
|
||||
ZAP SS,C(10) ss=ss/ii
|
||||
BR R14
|
||||
RETURN L R14,SAVER14 restore caller address
|
||||
XR R15,R15
|
||||
BR R14
|
||||
SAVER14 DS F
|
||||
NN EQU 10
|
||||
NA DC AL2(NN)
|
||||
A DS (NN)PL6
|
||||
II DS PL6
|
||||
SS DS PL6
|
||||
P DS H
|
||||
N DS H
|
||||
C DS CL16
|
||||
BUF DC CL30' ' buffer
|
||||
EDMASK DC X'4020202020202021204B202020' CL13
|
||||
YREGS
|
||||
END AVGSMA
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
MODE SMAOBJ = STRUCT(
|
||||
LONG REAL sma,
|
||||
LONG REAL sum,
|
||||
INT period,
|
||||
REF[]LONG REAL values,
|
||||
INT lv
|
||||
);
|
||||
|
||||
MODE SMARESULT = UNION (
|
||||
REF SMAOBJ # handle #,
|
||||
LONG REAL # sma #,
|
||||
REF[]LONG REAL # values #
|
||||
);
|
||||
|
||||
MODE SMANEW = INT,
|
||||
SMAFREE = STRUCT(REF SMAOBJ free obj),
|
||||
SMAVALUES = STRUCT(REF SMAOBJ values obj),
|
||||
SMAADD = STRUCT(REF SMAOBJ add obj, LONG REAL v),
|
||||
SMAMEAN = STRUCT(REF SMAOBJ mean obj, REF[]LONG REAL v);
|
||||
|
||||
MODE ACTION = UNION ( SMANEW, SMAFREE, SMAVALUES, SMAADD, SMAMEAN );
|
||||
|
||||
PROC sma = ([]ACTION action)SMARESULT:
|
||||
(
|
||||
SMARESULT result;
|
||||
REF SMAOBJ obj;
|
||||
LONG REAL v;
|
||||
|
||||
FOR i FROM LWB action TO UPB action DO
|
||||
CASE action[i] IN
|
||||
(SMANEW period):( # args: INT period #
|
||||
HEAP SMAOBJ handle;
|
||||
sma OF handle := 0.0;
|
||||
period OF handle := period;
|
||||
values OF handle := HEAP [period OF handle]LONG REAL;
|
||||
lv OF handle := 0;
|
||||
sum OF handle := 0.0;
|
||||
result := handle
|
||||
),
|
||||
(SMAFREE args):( # args: REF SMAOBJ free obj #
|
||||
free obj OF args := REF SMAOBJ(NIL) # let the garbage collector do it's job #
|
||||
),
|
||||
(SMAVALUES args):( # args: REF SMAOBJ values obj #
|
||||
result := values OF values obj OF args
|
||||
),
|
||||
(SMAMEAN args):( # args: REF SMAOBJ mean obj #
|
||||
result := sma OF mean obj OF args
|
||||
),
|
||||
(SMAADD args):( # args: REF SMAOBJ add obj, LONG REAL v #
|
||||
obj := add obj OF args;
|
||||
v := v OF args;
|
||||
IF lv OF obj < period OF obj THEN
|
||||
(values OF obj)[lv OF obj+:=1] := v;
|
||||
sum OF obj +:= v;
|
||||
sma OF obj := sum OF obj / lv OF obj
|
||||
ELSE
|
||||
sum OF obj -:= (values OF obj)[ 1+ lv OF obj MOD period OF obj];
|
||||
sum OF obj +:= v;
|
||||
sma OF obj := sum OF obj / period OF obj;
|
||||
(values OF obj)[ 1+ lv OF obj MOD period OF obj ] := v; lv OF obj+:=1
|
||||
FI;
|
||||
result := sma OF obj
|
||||
)
|
||||
OUT
|
||||
SKIP
|
||||
ESAC
|
||||
OD;
|
||||
result
|
||||
);
|
||||
|
||||
[]LONG REAL v = ( 1, 2, 3, 4, 5, 5, 4, 3, 2, 1 );
|
||||
|
||||
main: (
|
||||
INT i;
|
||||
|
||||
REF SMAOBJ h3 := ( sma(SMANEW(3)) | (REF SMAOBJ obj):obj );
|
||||
REF SMAOBJ h5 := ( sma(SMANEW(5)) | (REF SMAOBJ obj):obj );
|
||||
|
||||
FOR i FROM LWB v TO UPB v DO
|
||||
printf(($"next number "g(0,6)", SMA_3 = "g(0,6)", SMA_5 = "g(0,6)l$,
|
||||
v[i], (sma(SMAADD(h3, v[i]))|(LONG REAL r):r), ( sma(SMAADD(h5, v[i])) | (LONG REAL r):r )
|
||||
))
|
||||
OD#;
|
||||
|
||||
sma(SMAFREE(h3));
|
||||
sma(SMAFREE(h5))
|
||||
#
|
||||
)
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
#!/usr/bin/awk -f
|
||||
# Moving average over the first column of a data file
|
||||
BEGIN {
|
||||
P = 5;
|
||||
}
|
||||
|
||||
{
|
||||
x = $1;
|
||||
i = NR % P;
|
||||
MA += (x - Z[i]) / P;
|
||||
Z[i] = x;
|
||||
print MA;
|
||||
}
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
generic
|
||||
Max_Elements : Positive;
|
||||
type Number is digits <>;
|
||||
package Moving is
|
||||
procedure Add_Number (N : Number);
|
||||
function Moving_Average (N : Number) return Number;
|
||||
function Get_Average return Number;
|
||||
end Moving;
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
with Ada.Containers.Vectors;
|
||||
|
||||
package body Moving is
|
||||
use Ada.Containers;
|
||||
|
||||
package Number_Vectors is new Ada.Containers.Vectors
|
||||
(Element_Type => Number,
|
||||
Index_Type => Natural);
|
||||
|
||||
Current_List : Number_Vectors.Vector := Number_Vectors.Empty_Vector;
|
||||
|
||||
procedure Add_Number (N : Number) is
|
||||
begin
|
||||
if Natural (Current_List.Length) >= Max_Elements then
|
||||
Current_List.Delete_First;
|
||||
end if;
|
||||
Current_List.Append (N);
|
||||
end Add_Number;
|
||||
|
||||
function Get_Average return Number is
|
||||
Average : Number := 0.0;
|
||||
procedure Sum (Position : Number_Vectors.Cursor) is
|
||||
begin
|
||||
Average := Average + Number_Vectors.Element (Position);
|
||||
end Sum;
|
||||
begin
|
||||
Current_List.Iterate (Sum'Access);
|
||||
if Current_List.Length > 1 then
|
||||
Average := Average / Number (Current_List.Length);
|
||||
end if;
|
||||
return Average;
|
||||
end Get_Average;
|
||||
|
||||
function Moving_Average (N : Number) return Number is
|
||||
begin
|
||||
Add_Number (N);
|
||||
return Get_Average;
|
||||
end Moving_Average;
|
||||
|
||||
end Moving;
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
with Ada.Text_IO;
|
||||
with Moving;
|
||||
procedure Main is
|
||||
package Three_Average is new Moving (Max_Elements => 3, Number => Float);
|
||||
package Five_Average is new Moving (Max_Elements => 5, Number => Float);
|
||||
begin
|
||||
for I in 1 .. 5 loop
|
||||
Ada.Text_IO.Put_Line ("Inserting" & Integer'Image (I) &
|
||||
" into max-3: " & Float'Image (Three_Average.Moving_Average (Float (I))));
|
||||
Ada.Text_IO.Put_Line ("Inserting" & Integer'Image (I) &
|
||||
" into max-5: " & Float'Image (Five_Average.Moving_Average (Float (I))));
|
||||
end loop;
|
||||
for I in reverse 1 .. 5 loop
|
||||
Ada.Text_IO.Put_Line ("Inserting" & Integer'Image (I) &
|
||||
" into max-3: " & Float'Image (Three_Average.Moving_Average (Float (I))));
|
||||
Ada.Text_IO.Put_Line ("Inserting" & Integer'Image (I) &
|
||||
" into max-5: " & Float'Image (Five_Average.Moving_Average (Float (I))));
|
||||
end loop;
|
||||
end Main;
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
MsgBox % MovingAverage(5,3) ; 5, averaging length <- 3
|
||||
MsgBox % MovingAverage(1) ; 3
|
||||
MsgBox % MovingAverage(-3) ; 1
|
||||
MsgBox % MovingAverage(8) ; 2
|
||||
MsgBox % MovingAverage(7) ; 4
|
||||
|
||||
MovingAverage(x,len="") { ; for integers (faster)
|
||||
Static
|
||||
Static sum:=0, n:=0, m:=10 ; default averaging length = 10
|
||||
If (len>"") ; non-blank 2nd parameter: set length, reset
|
||||
sum := n := i := 0, m := len
|
||||
If (n < m) ; until the buffer is not full
|
||||
sum += x, n++ ; keep summing data
|
||||
Else ; when buffer is full
|
||||
sum += x-v%i% ; add new, subtract oldest
|
||||
v%i% := x, i := mod(i+1,m) ; remember last m inputs, cycle insertion point
|
||||
Return sum/n
|
||||
}
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
MovingAverage(x,len="") { ; for floating point numbers
|
||||
Static
|
||||
Static n:=0, m:=10 ; default averaging length = 10
|
||||
If (len>"") ; non-blank 2nd parameter: set length, reset
|
||||
n := i := 0, m := len
|
||||
n += n < m, sum := 0
|
||||
v%i% := x, i := mod(i+1,m) ; remember last m inputs, cycle insertion point
|
||||
Loop %n% ; recompute sum to avoid error accumulation
|
||||
j := A_Index-1, sum += v%j%
|
||||
Return sum/n
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
MAXPERIOD = 10
|
||||
FOR n = 1 TO 5
|
||||
PRINT "Number = ";n TAB(12) " SMA3 = ";FNsma(n,3) TAB(30) " SMA5 = ";FNsma(n,5)
|
||||
NEXT
|
||||
FOR n = 5 TO 1 STEP -1
|
||||
PRINT "Number = ";n TAB(12) " SMA3 = ";FNsma(n,3) TAB(30) " SMA5 = ";FNsma(n,5)
|
||||
NEXT
|
||||
END
|
||||
|
||||
DEF FNsma(number, period%)
|
||||
PRIVATE nums(), accum(), index%(), window%()
|
||||
DIM nums(MAXPERIOD,MAXPERIOD), accum(MAXPERIOD)
|
||||
DIM index%(MAXPERIOD), window%(MAXPERIOD)
|
||||
accum(period%) += number - nums(period%,index%(period%))
|
||||
nums(period%,index%(period%)) = number
|
||||
index%(period%) = (index%(period%) + 1) MOD period%
|
||||
IF window%(period%)<period% window%(period%) += 1
|
||||
= accum(period%) / window%(period%)
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
( ( I
|
||||
= buffer
|
||||
. (new$=):?freshEmptyBuffer
|
||||
&
|
||||
' ( buffer avg
|
||||
. ( avg
|
||||
= L S n
|
||||
. 0:?L:?S
|
||||
& whl
|
||||
' ( !arg:%?n ?arg
|
||||
& !n+!S:?S
|
||||
& 1+!L:?L
|
||||
)
|
||||
& (!L:0&0|!S*!L^-1)
|
||||
)
|
||||
& (buffer=$freshEmptyBuffer)
|
||||
& !arg !(buffer.):?(buffer.)
|
||||
& ( !(buffer.):?(buffer.) [($arg) ?
|
||||
|
|
||||
)
|
||||
& avg$!(buffer.)
|
||||
)
|
||||
)
|
||||
& ( pad
|
||||
= len w
|
||||
. @(!arg:? [?len)
|
||||
& @(" ":? [!len ?w)
|
||||
& !w !arg
|
||||
)
|
||||
& I$3:(=?sma3)
|
||||
& I$5:(=?sma5)
|
||||
& 1 2 3 4 5 5 4 3 2 1:?K
|
||||
& whl
|
||||
' ( !K:%?k ?K
|
||||
& out
|
||||
$ (str$(!k " - sma3:" pad$(sma3$!k) " sma5:" pad$(sma5$!k)))
|
||||
)
|
||||
);
|
||||
|
|
@ -0,0 +1,21 @@
|
|||
SMA = object.new
|
||||
|
||||
SMA.init = { period |
|
||||
my.period = period
|
||||
my.list = []
|
||||
my.average = 0
|
||||
}
|
||||
|
||||
SMA.prototype.add = { num |
|
||||
true? my.list.length >= my.period
|
||||
{ my.list.deq }
|
||||
|
||||
my.list << num
|
||||
my.average = my.list.reduce(:+) / my.list.length
|
||||
}
|
||||
|
||||
sma3 = SMA.new 3
|
||||
sma5 = SMA.new 5
|
||||
[1, 2, 3, 4, 5, 5, 4, 3, 2, 1].each { n |
|
||||
p n, " - SMA3: ", sma3.add(n), " SMA5: ", sma5.add(n)
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
sma = { period |
|
||||
list = []
|
||||
|
||||
{ num |
|
||||
true? list.length >= period
|
||||
{ list.deq }
|
||||
|
||||
list << num
|
||||
list.reduce(:+) / list.length
|
||||
}
|
||||
}
|
||||
|
||||
sma3 = sma 3
|
||||
sma5 = sma 5
|
||||
[1, 2, 3, 4, 5, 5, 4, 3, 2, 1].each { n |
|
||||
p n, " - SMA3: ", sma3(n), " SMA5: ", sma5(n)
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
#include <iostream>
|
||||
#include <stddef.h>
|
||||
#include <assert.h>
|
||||
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
|
||||
class SMA {
|
||||
public:
|
||||
SMA(unsigned int period) :
|
||||
period(period), window(new double[period]), head(NULL), tail(NULL),
|
||||
total(0) {
|
||||
assert(period >= 1);
|
||||
}
|
||||
~SMA() {
|
||||
delete[] window;
|
||||
}
|
||||
|
||||
// Adds a value to the average, pushing one out if nescessary
|
||||
void add(double val) {
|
||||
// Special case: Initialization
|
||||
if (head == NULL) {
|
||||
head = window;
|
||||
*head = val;
|
||||
tail = head;
|
||||
inc(tail);
|
||||
total = val;
|
||||
return;
|
||||
}
|
||||
|
||||
// Were we already full?
|
||||
if (head == tail) {
|
||||
// Fix total-cache
|
||||
total -= *head;
|
||||
// Make room
|
||||
inc(head);
|
||||
}
|
||||
|
||||
// Write the value in the next spot.
|
||||
*tail = val;
|
||||
inc(tail);
|
||||
|
||||
// Update our total-cache
|
||||
total += val;
|
||||
}
|
||||
|
||||
// Returns the average of the last P elements added to this SMA.
|
||||
// If no elements have been added yet, returns 0.0
|
||||
double avg() const {
|
||||
ptrdiff_t size = this->size();
|
||||
if (size == 0) {
|
||||
return 0; // No entries => 0 average
|
||||
}
|
||||
return total / (double) size; // Cast to double for floating point arithmetic
|
||||
}
|
||||
|
||||
private:
|
||||
unsigned int period;
|
||||
double * window; // Holds the values to calculate the average of.
|
||||
|
||||
// Logically, head is before tail
|
||||
double * head; // Points at the oldest element we've stored.
|
||||
double * tail; // Points at the newest element we've stored.
|
||||
|
||||
double total; // Cache the total so we don't sum everything each time.
|
||||
|
||||
// Bumps the given pointer up by one.
|
||||
// Wraps to the start of the array if needed.
|
||||
void inc(double * & p) {
|
||||
if (++p >= window + period) {
|
||||
p = window;
|
||||
}
|
||||
}
|
||||
|
||||
// Returns how many numbers we have stored.
|
||||
ptrdiff_t size() const {
|
||||
if (head == NULL)
|
||||
return 0;
|
||||
if (head == tail)
|
||||
return period;
|
||||
return (period + tail - head) % period;
|
||||
}
|
||||
};
|
||||
|
||||
int main(int argc, char * * argv) {
|
||||
SMA foo(3);
|
||||
SMA bar(5);
|
||||
|
||||
int data[] = { 1, 2, 3, 4, 5, 5, 4, 3, 2, 1 };
|
||||
for (int * itr = data; itr < data + 10; itr++) {
|
||||
foo.add(*itr);
|
||||
cout << "Added " << *itr << " avg: " << foo.avg() << endl;
|
||||
}
|
||||
cout << endl;
|
||||
for (int * itr = data; itr < data + 10; itr++) {
|
||||
bar.add(*itr);
|
||||
cout << "Added " << *itr << " avg: " << bar.avg() << endl;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
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();
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
typedef struct sma_obj {
|
||||
double sma;
|
||||
double sum;
|
||||
int period;
|
||||
double *values;
|
||||
int lv;
|
||||
} sma_obj_t;
|
||||
|
||||
typedef union sma_result {
|
||||
sma_obj_t *handle;
|
||||
double sma;
|
||||
double *values;
|
||||
} sma_result_t;
|
||||
|
||||
enum Action { SMA_NEW, SMA_FREE, SMA_VALUES, SMA_ADD, SMA_MEAN };
|
||||
sma_result_t sma(enum Action action, ...)
|
||||
{
|
||||
va_list vl;
|
||||
sma_result_t r;
|
||||
sma_obj_t *o;
|
||||
double v;
|
||||
|
||||
va_start(vl, action);
|
||||
switch(action) {
|
||||
case SMA_NEW: // args: int period
|
||||
r.handle = malloc(sizeof(sma_obj_t));
|
||||
r.handle->sma = 0.0;
|
||||
r.handle->period = va_arg(vl, int);
|
||||
r.handle->values = malloc(r.handle->period * sizeof(double));
|
||||
r.handle->lv = 0;
|
||||
r.handle->sum = 0.0;
|
||||
break;
|
||||
case SMA_FREE: // args: sma_obj_t *handle
|
||||
r.handle = va_arg(vl, sma_obj_t *);
|
||||
free(r.handle->values);
|
||||
free(r.handle);
|
||||
r.handle = NULL;
|
||||
break;
|
||||
case SMA_VALUES: // args: sma_obj_t *handle
|
||||
o = va_arg(vl, sma_obj_t *);
|
||||
r.values = o->values;
|
||||
break;
|
||||
case SMA_MEAN: // args: sma_obj_t *handle
|
||||
o = va_arg(vl, sma_obj_t *);
|
||||
r.sma = o->sma;
|
||||
break;
|
||||
case SMA_ADD: // args: sma_obj_t *handle, double value
|
||||
o = va_arg(vl, sma_obj_t *);
|
||||
v = va_arg(vl, double);
|
||||
if ( o->lv < o->period ) {
|
||||
o->values[o->lv++] = v;
|
||||
o->sum += v;
|
||||
o->sma = o->sum / o->lv;
|
||||
} else {
|
||||
o->sum -= o->values[ o->lv % o->period];
|
||||
o->sum += v;
|
||||
o->sma = o->sum / o->period;
|
||||
o->values[ o->lv % o->period ] = v; o->lv++;
|
||||
}
|
||||
r.sma = o->sma;
|
||||
break;
|
||||
}
|
||||
va_end(vl);
|
||||
return r;
|
||||
}
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
double v[] = { 1, 2, 3, 4, 5, 5, 4, 3, 2, 1 };
|
||||
|
||||
int main()
|
||||
{
|
||||
int i;
|
||||
|
||||
sma_obj_t *h3 = sma(SMA_NEW, 3).handle;
|
||||
sma_obj_t *h5 = sma(SMA_NEW, 5).handle;
|
||||
|
||||
for(i=0; i < sizeof(v)/sizeof(double) ; i++) {
|
||||
printf("next number %lf, SMA_3 = %lf, SMA_5 = %lf\n",
|
||||
v[i], sma(SMA_ADD, h3, v[i]).sma, sma(SMA_ADD, h5, v[i]).sma);
|
||||
}
|
||||
|
||||
sma(SMA_FREE, h3);
|
||||
sma(SMA_FREE, h5);
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
(import '[clojure.lang PersistentQueue])
|
||||
|
||||
(defn enqueue-max [q p n]
|
||||
(let [q (conj q n)]
|
||||
(if (<= (count q) p) q (pop q))))
|
||||
|
||||
(defn avg [coll] (/ (reduce + coll) (count coll)))
|
||||
|
||||
(defn init-moving-avg [p]
|
||||
(let [state (atom PersistentQueue/EMPTY)]
|
||||
(fn [n]
|
||||
(avg (swap! state enqueue-max p n)))))
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
I = (P) ->
|
||||
# The cryptic name "I" follows the problem description;
|
||||
# it returns a function that computes a moving average
|
||||
# of successive values over the period P, using closure
|
||||
# variables to maintain state.
|
||||
cq = circular_queue(P)
|
||||
num_elems = 0
|
||||
sum = 0
|
||||
|
||||
SMA = (n) ->
|
||||
sum += n
|
||||
if num_elems < P
|
||||
cq.add(n)
|
||||
num_elems += 1
|
||||
sum / num_elems
|
||||
else
|
||||
old = cq.replace(n)
|
||||
sum -= old
|
||||
sum / P
|
||||
|
||||
circular_queue = (n) ->
|
||||
# queue that only ever stores up to n values;
|
||||
# Caller shouldn't call replace until n values
|
||||
# have been added.
|
||||
i = 0
|
||||
arr = []
|
||||
|
||||
add: (elem) ->
|
||||
arr.push elem
|
||||
replace: (elem) ->
|
||||
# return value whose age is "n"
|
||||
old_val = arr[i]
|
||||
arr[i] = elem
|
||||
i = (i + 1) % n
|
||||
old_val
|
||||
|
||||
# The output of the code below should convince you that
|
||||
# calling I multiple times returns functions with independent
|
||||
# state.
|
||||
sma3 = I(3)
|
||||
sma7 = I(7)
|
||||
sma11 = I(11)
|
||||
for i in [1..10]
|
||||
console.log i, sma3(i), sma7(i), sma11(i)
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
(defun simple-moving-average (period &aux
|
||||
(sum 0) (count 0) (values (make-list period)) (pointer values))
|
||||
(setf (rest (last values)) values) ; construct circularity
|
||||
(lambda (n)
|
||||
(when (first pointer)
|
||||
(decf sum (first pointer))) ; subtract old value
|
||||
(incf sum n) ; add new value
|
||||
(incf count)
|
||||
(setf (first pointer) n)
|
||||
(setf pointer (rest pointer)) ; advance pointer
|
||||
(/ sum (min count period))))
|
||||
|
|
@ -0,0 +1 @@
|
|||
(mapcar '(simple-moving-average period) list-of-values)
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
import std.stdio, std.traits, std.algorithm;
|
||||
|
||||
auto sma(T, int period)() pure nothrow @safe {
|
||||
T[period] data = 0;
|
||||
T sum = 0;
|
||||
int index, nFilled;
|
||||
|
||||
return (in T v) nothrow @safe @nogc {
|
||||
sum += -data[index] + v;
|
||||
data[index] = v;
|
||||
index = (index + 1) % period;
|
||||
nFilled = min(period, nFilled + 1);
|
||||
return CommonType!(T, float)(sum) / nFilled;
|
||||
};
|
||||
}
|
||||
|
||||
void main() {
|
||||
immutable s3 = sma!(int, 3);
|
||||
immutable s5 = sma!(double, 5);
|
||||
|
||||
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));
|
||||
}
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
import std.stdio, std.traits, std.algorithm;
|
||||
|
||||
struct SMA(T, int period) {
|
||||
T[period] data = 0;
|
||||
T sum = 0;
|
||||
int index, nFilled;
|
||||
|
||||
auto opCall(in T v) pure nothrow @safe @nogc {
|
||||
sum += -data[index] + v;
|
||||
data[index] = v;
|
||||
index = (index + 1) % period;
|
||||
nFilled = min(period, nFilled + 1);
|
||||
return CommonType!(T, float)(sum) / nFilled;
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
SMA!(int, 3) s3;
|
||||
SMA!(double, 5) s5;
|
||||
|
||||
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));
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
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.
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
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))")
|
||||
}
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
pragma.enable("accumulator")
|
||||
def makeMovingAverage(period) {
|
||||
def values := ([null] * period).diverge()
|
||||
var index := 0
|
||||
var count := 0
|
||||
|
||||
def insert(v) {
|
||||
values[index] := v
|
||||
index := (index + 1) %% period
|
||||
count += 1
|
||||
}
|
||||
|
||||
/** Returns the simple moving average of the inputs so far, or null if there
|
||||
have been no inputs. */
|
||||
def average() {
|
||||
if (count > 0) {
|
||||
return accum 0 for x :notNull in values { _ + x } / count.min(period)
|
||||
}
|
||||
}
|
||||
|
||||
return [insert, average]
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
? for period in [3, 5] {
|
||||
> def [insert, average] := makeMovingAverage(period)
|
||||
> println(`Period $period:`)
|
||||
> for value in [1,2,3,4,5,5,4,3,2,1] {
|
||||
> insert(value)
|
||||
> println(value, "\t", average())
|
||||
> }
|
||||
> println()
|
||||
> }
|
||||
|
||||
Period 3:
|
||||
1 1.0
|
||||
2 1.5
|
||||
3 2.0
|
||||
4 3.0
|
||||
5 4.0
|
||||
5 4.666666666666667
|
||||
4 4.666666666666667
|
||||
3 4.0
|
||||
2 3.0
|
||||
1 2.0
|
||||
|
||||
Period 5:
|
||||
1 1.0
|
||||
2 1.5
|
||||
3 2.0
|
||||
4 2.5
|
||||
5 3.0
|
||||
5 3.8
|
||||
4 4.2
|
||||
3 4.2
|
||||
2 3.8
|
||||
1 3.0
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
(lib 'tree) ;; queues operations
|
||||
|
||||
|
||||
(define (make-sma p)
|
||||
(define Q (queue (gensym)))
|
||||
(lambda (item)
|
||||
(q-push Q item)
|
||||
(when (> (queue-length Q) p) (q-pop Q))
|
||||
(// (for/sum ((x (queue->list Q))) x) (queue-length Q))))
|
||||
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
import system'routines;
|
||||
import system'collections;
|
||||
import extensions;
|
||||
|
||||
class SMA
|
||||
{
|
||||
object thePeriod;
|
||||
object theList;
|
||||
|
||||
constructor new(period)
|
||||
{
|
||||
thePeriod := period;
|
||||
theList :=new List();
|
||||
}
|
||||
|
||||
append(n)
|
||||
{
|
||||
theList.append(n);
|
||||
|
||||
var count := theList.Length;
|
||||
count =>
|
||||
0 { ^0.0r }
|
||||
: {
|
||||
if (count > thePeriod)
|
||||
{
|
||||
theList.removeAt:0;
|
||||
|
||||
count := thePeriod
|
||||
};
|
||||
|
||||
var sum := theList.summarize(Real.new());
|
||||
|
||||
^ sum / count
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public program()
|
||||
{
|
||||
var SMA3 := SMA.new:3;
|
||||
var SMA5 := SMA.new:5;
|
||||
|
||||
for (int i := 1, i <= 5, i += 1) {
|
||||
console.printPaddingRight(30, "sma3 + ", i, " = ", SMA3.append:i);
|
||||
console.printLine("sma5 + ", i, " = ", SMA5.append:i)
|
||||
};
|
||||
|
||||
for (int i := 5, i >= 1, i -= 1) {
|
||||
console.printPaddingRight(30, "sma3 + ", i, " = ", SMA3.append:i);
|
||||
console.printLine("sma5 + ", i, " = ", SMA5.append:i)
|
||||
};
|
||||
|
||||
console.readChar()
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
$ cat simple-moving-avg.exs
|
||||
#!/usr/bin/env elixir
|
||||
|
||||
defmodule Math do
|
||||
def average([]), do: nil
|
||||
def average(enum) do
|
||||
Enum.sum(enum) / length(enum)
|
||||
end
|
||||
end
|
||||
|
||||
defmodule SMA do
|
||||
|
||||
def sma(l, p \\ 10) do
|
||||
IO.puts("\nSimple moving average(period=#{p}):")
|
||||
Enum.chunk(l, p, 1)
|
||||
|> Enum.map(&(%{"input": &1, "avg": Float.round(Math.average(&1), 3)}))
|
||||
end
|
||||
|
||||
defmacro gen_func(p) do
|
||||
quote do
|
||||
fn l -> SMA.sma(l, unquote(p)) end
|
||||
end
|
||||
end
|
||||
|
||||
def read_numeric_input do
|
||||
IO.stream(:stdio, :line)
|
||||
|> Enum.map(&(String.split(&1, ~r{\s+})))
|
||||
|> List.flatten()
|
||||
|> Enum.reject(&(is_nil(&1) || String.length(&1) == 0))
|
||||
|> Enum.map(&(Integer.parse(&1) |> elem(0)))
|
||||
end
|
||||
|
||||
def run do
|
||||
sma_func_10 = gen_func(10)
|
||||
sma_func_15 = gen_func(15)
|
||||
numbers = read_numeric_input
|
||||
sma_func_10.(numbers) |> IO.inspect
|
||||
sma_func_15.(numbers) |> IO.inspect
|
||||
end
|
||||
end
|
||||
|
||||
SMA.run
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
#!/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
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
main() ->
|
||||
SMA3 = sma(3),
|
||||
SMA5 = sma(5),
|
||||
Ns = [1, 2, 3, 4, 5, 5, 4, 3, 2, 1],
|
||||
lists:foreach(
|
||||
fun (N) ->
|
||||
io:format("Added ~b, sma(3) -> ~f, sma(5) -> ~f~n",[N,next(SMA3,N),next(SMA5,N)])
|
||||
end, Ns),
|
||||
stop(SMA3),
|
||||
stop(SMA5).
|
||||
|
||||
sma(W) ->
|
||||
{sma,spawn(?MODULE,loop,[W,[]])}.
|
||||
|
||||
loop(Window, Numbers) ->
|
||||
receive
|
||||
{_Pid, stop} ->
|
||||
ok;
|
||||
{Pid, N} when is_number(N) ->
|
||||
case length(Numbers) < Window of
|
||||
true ->
|
||||
Next = Numbers++[N];
|
||||
false ->
|
||||
Next = tl(Numbers)++[N]
|
||||
end,
|
||||
Pid ! {average, lists:sum(Next)/length(Next)},
|
||||
loop(Window,Next);
|
||||
_ ->
|
||||
ok
|
||||
end.
|
||||
|
||||
stop({sma,Pid}) ->
|
||||
Pid ! {self(),stop},
|
||||
ok.
|
||||
|
||||
next({sma,Pid},N) ->
|
||||
Pid ! {self(), N},
|
||||
receive
|
||||
{average, Ave} ->
|
||||
Ave
|
||||
end.
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
9> sma:main().
|
||||
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
|
||||
ok
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
>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
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
>function store (x:number, v:vector, n:index) ...
|
||||
$if cols(v)<n then return v|x;
|
||||
$else
|
||||
$ v=rotleft(v); v[-1]=x;
|
||||
$ return v;
|
||||
$endif;
|
||||
$endfunction
|
||||
>v=zeros(1,0); for k=1:20; v=store(k,v,10); mean(v), end;
|
||||
1
|
||||
1.5
|
||||
2
|
||||
2.5
|
||||
3
|
||||
3.5
|
||||
4
|
||||
4.5
|
||||
5
|
||||
5.5
|
||||
6.5
|
||||
7.5
|
||||
8.5
|
||||
9.5
|
||||
10.5
|
||||
11.5
|
||||
12.5
|
||||
13.5
|
||||
14.5
|
||||
15.5
|
||||
>v
|
||||
[ 11 12 13 14 15 16 17 18 19 20 ]
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
let sma period f (list:float list) =
|
||||
let sma_aux queue v =
|
||||
let q = Seq.truncate period (v :: queue)
|
||||
Seq.average q, Seq.toList q
|
||||
List.fold (fun s v ->
|
||||
let avg,state = sma_aux s v
|
||||
f avg
|
||||
state) [] list
|
||||
|
||||
printf "sma3: "
|
||||
[ 1.;2.;3.;4.;5.;5.;4.;3.;2.;1.] |> sma 3 (printf "%.2f ")
|
||||
printf "\nsma5: "
|
||||
[ 1.;2.;3.;4.;5.;5.;4.;3.;2.;1.] |> sma 5 (printf "%.2f ")
|
||||
printfn ""
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
class MovingAverage
|
||||
{
|
||||
Int period
|
||||
Int[] stream
|
||||
|
||||
new make (Int period)
|
||||
{
|
||||
this.period = period
|
||||
stream = [,]
|
||||
}
|
||||
|
||||
// add number to end of stream and remove numbers from start if
|
||||
// stream is larger than period
|
||||
public Void addNumber (Int number)
|
||||
{
|
||||
stream.add (number)
|
||||
while (stream.size > period)
|
||||
{
|
||||
stream.removeAt (0)
|
||||
}
|
||||
}
|
||||
|
||||
// compute average of numbers in stream
|
||||
public Float average ()
|
||||
{
|
||||
if (stream.isEmpty)
|
||||
return 0.0f
|
||||
else
|
||||
1.0f * (Int)(stream.reduce(0, |a,b| { (Int) a + b })) / stream.size
|
||||
}
|
||||
}
|
||||
|
||||
class Main
|
||||
{
|
||||
public static Void main ()
|
||||
{ // test by adding random numbers and printing average after each number
|
||||
av := MovingAverage (5)
|
||||
|
||||
10.times |i|
|
||||
{
|
||||
echo ("After $i numbers list is ${av.stream} average is ${av.average}")
|
||||
av.addNumber (Int.random(0..100))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
: f+! ( f addr -- ) dup f@ f+ f! ;
|
||||
: ,f0s ( n -- ) falign 0 do 0e f, loop ;
|
||||
|
||||
: period @ ;
|
||||
: used cell+ ;
|
||||
: head 2 cells + ;
|
||||
: sum 3 cells + faligned ;
|
||||
: ring ( addr -- faddr )
|
||||
dup sum float+ swap head @ floats + ;
|
||||
|
||||
: update ( fvalue addr -- addr )
|
||||
dup ring f@ fnegate dup sum f+!
|
||||
fdup dup ring f! dup sum f+!
|
||||
dup head @ 1+ over period mod over head ! ;
|
||||
|
||||
: moving-average
|
||||
create ( period -- ) dup , 0 , 0 , 1+ ,f0s
|
||||
does> ( fvalue -- avg )
|
||||
update
|
||||
dup used @ over period < if 1 over used +! then
|
||||
dup sum f@ used @ 0 d>f f/ ;
|
||||
|
||||
3 moving-average sma
|
||||
1e sma f. \ 1.
|
||||
2e sma f. \ 1.5
|
||||
3e sma f. \ 2.
|
||||
4e sma f. \ 3.
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
program Movavg
|
||||
implicit none
|
||||
|
||||
integer :: i
|
||||
|
||||
write (*, "(a)") "SIMPLE MOVING AVERAGE: PERIOD = 3"
|
||||
|
||||
do i = 1, 5
|
||||
write (*, "(a, i2, a, f8.6)") "Next number:", i, " sma = ", sma(real(i))
|
||||
end do
|
||||
do i = 5, 1, -1
|
||||
write (*, "(a, i2, a, f8.6)") "Next number:", i, " sma = ", sma(real(i))
|
||||
end do
|
||||
|
||||
contains
|
||||
|
||||
function sma(n)
|
||||
real :: sma
|
||||
real, intent(in) :: n
|
||||
real, save :: a(3) = 0
|
||||
integer, save :: count = 0
|
||||
|
||||
if (count < 3) then
|
||||
count = count + 1
|
||||
a(count) = n
|
||||
else
|
||||
a = eoshift(a, 1, n)
|
||||
end if
|
||||
|
||||
sma = sum(a(1:count)) / real(count)
|
||||
end function
|
||||
|
||||
end program Movavg
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
' 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
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
MovingAverage := function(n)
|
||||
local sma, buffer, pos, sum, len;
|
||||
buffer := List([1 .. n], i -> 0);
|
||||
pos := 0;
|
||||
len := 0;
|
||||
sum := 0;
|
||||
sma := function(x)
|
||||
pos := RemInt(pos, n) + 1;
|
||||
sum := sum + x - buffer[pos];
|
||||
buffer[pos] := x;
|
||||
len := Minimum(len + 1, n);
|
||||
return sum/len;
|
||||
end;
|
||||
return sma;
|
||||
end;
|
||||
|
||||
f := MovingAverage(3);
|
||||
f(1); # 1
|
||||
f(2); # 3/2
|
||||
f(3); # 2
|
||||
f(4); # 3
|
||||
f(5); # 4
|
||||
f(5); # 14/3
|
||||
f(4); # 14/3
|
||||
f(3); # 4
|
||||
f(2); # 3
|
||||
f(1); # 2
|
||||
|
|
@ -0,0 +1,31 @@
|
|||
package main
|
||||
|
||||
import "fmt"
|
||||
|
||||
func sma(period int) func(float64) float64 {
|
||||
var i int
|
||||
var sum float64
|
||||
var storage = make([]float64, 0, period)
|
||||
|
||||
return func(input float64) (avrg float64) {
|
||||
if len(storage) < period {
|
||||
sum += input
|
||||
storage = append(storage, input)
|
||||
}
|
||||
|
||||
sum += input - storage[i]
|
||||
storage[i], i = input, (i+1)%period
|
||||
avrg = sum / float64(len(storage))
|
||||
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
func main() {
|
||||
sma3 := sma(3)
|
||||
sma5 := sma(5)
|
||||
fmt.Println("x sma3 sma5")
|
||||
for _, x := range []float64{1, 2, 3, 4, 5, 5, 4, 3, 2, 1} {
|
||||
fmt.Printf("%5.3f %5.3f %5.3f\n", x, sma3(x), sma5(x))
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,15 @@
|
|||
def simple_moving_average = { size ->
|
||||
def nums = []
|
||||
double total = 0.0
|
||||
return { newElement ->
|
||||
nums += newElement
|
||||
oldestElement = nums.size() > size ? nums.remove(0) : 0
|
||||
total += newElement - oldestElement
|
||||
total / nums.size()
|
||||
}
|
||||
}
|
||||
|
||||
ma5 = simple_moving_average(5)
|
||||
|
||||
(1..5).each{ printf( "%1.1f ", ma5(it)) }
|
||||
(5..1).each{ printf( "%1.1f ", ma5(it)) }
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
{-# LANGUAGE BangPatterns #-}
|
||||
|
||||
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)
|
||||
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)
|
||||
mkSMA period = avgr <$> newIORef []
|
||||
where avgr nsref x = readIORef nsref >>= (\ns ->
|
||||
let xs = take period (x:ns)
|
||||
in writeIORef nsref xs $> mean xs)
|
||||
|
||||
main = mkSMA 3 >>= (\sma3 -> mkSMA 5 >>= (\sma5 ->
|
||||
mapM_ (str <$> pure n <*> sma3 <*> sma5) series))
|
||||
where str n mm3 mm5 =
|
||||
concat ["Next number = ",show n,", SMA_3 = ",show mm3,", SMA_5 = ",show mm5]
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
import Data.List
|
||||
import Control.Arrow
|
||||
import Control.Monad
|
||||
|
||||
sMA p = map (head *** head ).tail.
|
||||
scanl (\(y,_) -> (id &&& return. av) . (: if length y == p then init y else y)) ([],[])
|
||||
where av = liftM2 (/) sum (fromIntegral.length)
|
||||
|
||||
printSMA n p = mapM_ (\(n,a) -> putStrLn $ "Next number: " ++ show n ++ " Average: " ++ show a)
|
||||
. take n . sMA p $ [1..5]++[5,4..1]++[3..]
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
import Control.Monad
|
||||
import Control.Monad.State
|
||||
|
||||
period :: Int
|
||||
period = 3
|
||||
|
||||
type SMAState = [Float]
|
||||
|
||||
computeSMA :: Float -> State SMAState Float
|
||||
computeSMA x = do
|
||||
previousValues <- get
|
||||
let values = previousValues ++ [x]
|
||||
let newAverage = if length values <= period then (sum values) / (fromIntegral $ length remainingValues :: Float)
|
||||
else (sum remainingValues) / (fromIntegral $ length remainingValues :: Float)
|
||||
where remainingValues = dropIf period values
|
||||
put $ dropIf period values
|
||||
return newAverage
|
||||
|
||||
dropIf :: Int -> [a] -> [a]
|
||||
dropIf x xs = drop ((length xs) - x) xs
|
||||
|
||||
demostrateSMA :: State SMAState [Float]
|
||||
demostrateSMA = mapM computeSMA [1, 2, 3, 4, 5, 5, 4, 3, 2, 1]
|
||||
|
||||
main :: IO ()
|
||||
main = print $ evalState demostrateSMA []
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
REAL :: n=10, nums(n)
|
||||
|
||||
nums = (1,2,3,4,5, 5,4,3,2,1)
|
||||
DO i = 1, n
|
||||
WRITE() "num=", i, "SMA3=", SMA(3,nums(i)), "SMA5=",SMA(5,nums(i))
|
||||
ENDDO
|
||||
|
||||
END ! of "main"
|
||||
|
||||
FUNCTION SMA(period, num) ! maxID independent streams
|
||||
REAL :: maxID=10, now(maxID), Periods(maxID), Offsets(maxID), Pool(1000)
|
||||
|
||||
ID = INDEX(Periods, period)
|
||||
IF( ID == 0) THEN ! initialization
|
||||
IDs = IDs + 1
|
||||
ID = IDs
|
||||
Offsets(ID) = SUM(Periods) + 1
|
||||
Periods(ID) = period
|
||||
ENDIF
|
||||
|
||||
now(ID) = now(ID) + 1
|
||||
ALIAS(Pool,Offsets(ID), Past,Periods(ID)) ! renames relevant part of data pool
|
||||
Past = Past($+1) ! shift left
|
||||
Past(Periods(ID)) = num
|
||||
SMA = SUM(Past) / MIN( now(ID), Periods(ID) )
|
||||
END
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
procedure main(A)
|
||||
sma := buildSMA(3) # Use better name than "I".
|
||||
every write(sma(!A))
|
||||
end
|
||||
|
||||
procedure buildSMA(P)
|
||||
local stream
|
||||
c := create {
|
||||
stream := []
|
||||
while n := (avg@&source)[1] do {
|
||||
put(stream, n)
|
||||
if *stream > P then pop(stream)
|
||||
every (avg := 0.0) +:= !stream
|
||||
avg := avg/*stream
|
||||
}
|
||||
}
|
||||
return (@c, c)
|
||||
end
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
import Utils
|
||||
|
||||
procedure main(A)
|
||||
sma1 := closure(SMA,[],3)
|
||||
sma2 := closure(SMA,[],4)
|
||||
every every n := !A do write(left(sma1(n),20), sma2(n))
|
||||
end
|
||||
|
||||
procedure SMA(stream,P,n)
|
||||
put(stream, n)
|
||||
if *stream > P then pop(stream)
|
||||
every (avg := 0.0) +:= !stream
|
||||
return avg / *stream
|
||||
end
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
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
|
||||
|
|
@ -0,0 +1 @@
|
|||
lex =: 1 :'(a[n__a=.m#_.[a=.18!:3$~0)&(4 :''(+/%#)(#~1-128!:5)n__x=.1|.!.y n__x'')'
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
avg=: +/ % #
|
||||
SEQ=:''
|
||||
moveAvg=:4 :0"0
|
||||
SEQ=:SEQ,y
|
||||
avg ({.~ x -@<. #) SEQ
|
||||
)
|
||||
|
||||
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
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
import java.util.LinkedList;
|
||||
import java.util.Queue;
|
||||
|
||||
public class MovingAverage {
|
||||
private final Queue<Double> window = new LinkedList<Double>();
|
||||
private final int period;
|
||||
private double sum;
|
||||
|
||||
public MovingAverage(int period) {
|
||||
assert period > 0 : "Period must be a positive integer";
|
||||
this.period = period;
|
||||
}
|
||||
|
||||
public void newNum(double num) {
|
||||
sum += num;
|
||||
window.add(num);
|
||||
if (window.size() > period) {
|
||||
sum -= window.remove();
|
||||
}
|
||||
}
|
||||
|
||||
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);
|
||||
for (double x : testData) {
|
||||
ma.newNum(x);
|
||||
System.out.println("Next number = " + x + ", SMA = " + ma.getAvg());
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
function simple_moving_averager(period) {
|
||||
var nums = [];
|
||||
return function(num) {
|
||||
nums.push(num);
|
||||
if (nums.length > period)
|
||||
nums.splice(0,1); // remove the first element of the array
|
||||
var sum = 0;
|
||||
for (var i in nums)
|
||||
sum += nums[i];
|
||||
var n = period;
|
||||
if (nums.length < period)
|
||||
n = nums.length;
|
||||
return(sum/n);
|
||||
}
|
||||
}
|
||||
|
||||
var sma3 = simple_moving_averager(3);
|
||||
var sma5 = simple_moving_averager(5);
|
||||
var data = [1,2,3,4,5,5,4,3,2,1];
|
||||
for (var i in data) {
|
||||
var n = data[i];
|
||||
// using WSH
|
||||
WScript.Echo("Next number = " + n + ", SMA_3 = " + sma3(n) + ", SMA_5 = " + sma5(n));
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
// single-sided
|
||||
Array.prototype.simpleSMA=function(N) {
|
||||
return this.map(
|
||||
function(el,index, _arr) {
|
||||
return _arr.filter(
|
||||
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,9,10];
|
||||
console.log(g.simpleSMA(3));
|
||||
console.log(g.simpleSMA(5));
|
||||
console.log(g.simpleSMA(g.length));
|
||||
|
|
@ -0,0 +1 @@
|
|||
using Statistics
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
function movingaverage(::Type{T} = Float64; lim::Integer = -1) where T<:Real
|
||||
buffer = Vector{T}(0)
|
||||
if lim == -1
|
||||
# unlimited buffer
|
||||
return (y::T) -> begin
|
||||
push!(buffer, y)
|
||||
return mean(buffer)
|
||||
end
|
||||
else
|
||||
# limited size buffer
|
||||
return (y) -> begin
|
||||
push!(buffer, y)
|
||||
if length(buffer) > lim shift!(buffer) end
|
||||
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])
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
v:v,|v:1+!5
|
||||
v
|
||||
1 2 3 4 5 5 4 3 2 1
|
||||
|
||||
avg:{(+/x)%#x}
|
||||
sma:{avg'x@(,\!y),(1+!y)+\:!y}
|
||||
|
||||
sma[v;5]
|
||||
1 1.5 2 2.5 3 3.8 4.2 4.2 3.8 3
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
// 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)}")
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
define simple_moving_average(a::array,s::integer)::decimal => {
|
||||
#a->size == 0 ? return 0.00
|
||||
#s == 0 ? return 0.00
|
||||
#a->size == 1 ? return decimal(#a->first)
|
||||
#s == 1 ? return decimal(#a->last)
|
||||
local(na = array)
|
||||
if(#a->size <= #s) => {
|
||||
#na = #a
|
||||
else
|
||||
local(ar = #a->ascopy)
|
||||
#ar->reverse
|
||||
loop(#s) => { #na->insert(#ar->get(loop_count)) }
|
||||
}
|
||||
#s > #na->size ? #s = #na->size
|
||||
return (with e in #na sum #e) / decimal(#s)
|
||||
}
|
||||
// tests:
|
||||
'SMA 3 on array(1,2,3,4,5,5,4,3,2,1): '
|
||||
simple_moving_average(array(1,2,3,4,5,5,4,3,2,1),3)
|
||||
|
||||
'\rSMA 5 on array(1,2,3,4,5,5,4,3,2,1): '
|
||||
simple_moving_average(array(1,2,3,4,5,5,4,3,2,1),5)
|
||||
|
||||
'\r\rFurther example: \r'
|
||||
local(mynumbers = array, sma_num = 5)
|
||||
loop(10) => {^
|
||||
#mynumbers->insert(integer_random(1,100))
|
||||
#mynumbers->size + ' numbers: ' + #mynumbers
|
||||
' SMA3 is: ' + simple_moving_average(#mynumbers,3)
|
||||
', SMA5 is: ' + simple_moving_average(#mynumbers,5)
|
||||
'\r'
|
||||
^}
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
dim v$( 100) ' Each array term stores a particular SMA of period p in p*10 bytes
|
||||
|
||||
nomainwin
|
||||
|
||||
WindowWidth =1080
|
||||
WindowHeight = 780
|
||||
|
||||
graphicbox #w.gb1, 20, 20, 1000, 700
|
||||
|
||||
open "Running averages to smooth data" for window as #w
|
||||
|
||||
#w "trapclose quit"
|
||||
|
||||
#w.gb1 "down"
|
||||
|
||||
old.x = 0
|
||||
old.y.orig =500 ' black
|
||||
old.y.3.SMA =350 ' red
|
||||
old.y.20.SMA =300 ' green
|
||||
|
||||
for i =0 to 999 step 1
|
||||
scan
|
||||
v =1.1 +sin( i /1000 *2 *3.14159265) + 0.2 *rnd( 1) ' sin wave with added random noise
|
||||
x =i /6.28318 *1000
|
||||
y.orig =500 -v /2.5 *500
|
||||
|
||||
#w.gb1 "color black ; down ; line "; i-1; " "; old.y.orig; " "; i; " "; y.orig; " ; up"
|
||||
|
||||
y.3.SMA =500 -SMA( 1, v, 3) /2.5 *500 ' SMA given ID of 1 is to do 3-term running average
|
||||
#w.gb1 "color red ; down ; line "; i-1; " "; old.y.3.SMA +50; " "; i; " "; y.3.SMA +50; " ; up"
|
||||
|
||||
y.20.SMA =500 -SMA( 2, v, 20) /2.5 *500 ' SMA given ID of 2 is to do 20-term running average
|
||||
#w.gb1 "color green ; down ; line "; i-1; " "; old.y.20.SMA +100; " "; i; " "; y.20.SMA +100; " ; up"
|
||||
|
||||
'print "Supplied with "; v; ", so SMAs are now "; using( "###.###", SMA( 1, v, 3)); " over 3 terms or "; using( "###.###", SMA( 2, v, 5)) ; " over 5 terms." ' ID, latest data, period
|
||||
|
||||
old.y.orig =y.orig
|
||||
old.y.3.SMA =y.3.SMA
|
||||
old.y.20.SMA =y.20.SMA
|
||||
next i
|
||||
|
||||
wait
|
||||
|
||||
sub quit j$
|
||||
close #w
|
||||
end
|
||||
end sub
|
||||
|
||||
|
||||
|
||||
function SMA( ID, Number, Period)
|
||||
v$( ID) =right$( " " +str$( Number), 10) +v$( ID) ' add new number at left, lose last number on right
|
||||
v$( ID) =left$( v$( ID), Period *10)
|
||||
'print "{"; v$( ID); "}",
|
||||
|
||||
k =0 ' number of terms read
|
||||
total =0 ' sum of terms read
|
||||
|
||||
do
|
||||
p$ =mid$( v$( ID), 1 +k *10, 10)
|
||||
if p$ ="" then exit do
|
||||
vv =val( p$)
|
||||
total =total +vv
|
||||
k =k +1
|
||||
loop until p$ =""
|
||||
|
||||
if k <Period then SMA =total / k else SMA =total /Period
|
||||
end function
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
to average :l
|
||||
output quotient apply "sum :l count :l
|
||||
end
|
||||
|
||||
to make.sma :name :period
|
||||
localmake "qn word :name ".queue
|
||||
make :qn []
|
||||
define :name `[ [n] ; parameter list
|
||||
[if equal? count :,:qn ,:period [ignore dequeue ",:qn]]
|
||||
[queue ",:qn :n]
|
||||
[output average :,:qn]
|
||||
]
|
||||
end
|
||||
|
||||
make.sma "avg3 3
|
||||
|
||||
show map "avg3 [1 2 3 4 5] ; [1 1.5 2 3 4]
|
||||
|
||||
show text "avg3 ; examine what substitutions took place
|
||||
[[n] [if equal? count :avg3.queue 3 [ignore dequeue "avg3.queue]] [queue "avg3.queue :n] [output average :avg3.queue]]
|
||||
|
||||
; the internal queue is in the global namespace, easy to inspect
|
||||
show :avg3.queue ; [3 4 5]
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
...
|
||||
localmake "qn word :name gensym
|
||||
...
|
||||
|
||||
; list user-defined functions and variables
|
||||
show procedures ; [average avg3 make.sma]
|
||||
show names ; [[[] [avg3.g1]]
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
function sma(period)
|
||||
local t = {}
|
||||
function sum(t)
|
||||
sum = 0
|
||||
for _, v in ipairs(t) do
|
||||
sum = sum + v
|
||||
end
|
||||
return sum
|
||||
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
|
||||
|
||||
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
|
||||
|
|
@ -0,0 +1 @@
|
|||
[m,z] = filter(ones(1,P),P,x);
|
||||
|
|
@ -0,0 +1 @@
|
|||
[m,z] = filter(ones(1,P),P,x,z);
|
||||
|
|
@ -0,0 +1 @@
|
|||
MA[x_List, r_] := Join[Table[Mean[x[[1;;y]]],{y,r-1}], MovingAverage[x,r]]
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
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]]]
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
% state(period, list of floats from [newest, ..., oldest])
|
||||
:- type state ---> state(int, list(float)).
|
||||
|
||||
:- func init(int) = state.
|
||||
init(Period) = state(Period, []).
|
||||
|
||||
:- pred sma(float::in, float::out, state::in, state::out) is det.
|
||||
sma(N, Average, state(P, L0), state(P, L)) :-
|
||||
take_upto(P, [N|L0], L),
|
||||
Average = foldl((+), L, 0.0) / float(length(L)).
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/* NetRexx */
|
||||
options replace format comments java crossref symbols nobinary
|
||||
|
||||
numeric digits 20
|
||||
|
||||
class RAvgSimpleMoving public
|
||||
|
||||
properties private
|
||||
window = java.util.Queue
|
||||
period
|
||||
sum
|
||||
|
||||
properties constant
|
||||
exMsg = 'Period must be a positive integer'
|
||||
|
||||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
method RAvgSimpleMoving(period_) public
|
||||
if \period_.datatype('w') then signal RuntimeException(exMsg)
|
||||
if period_ <= 0 then signal RuntimeException(exMsg)
|
||||
window = LinkedList()
|
||||
period = period_
|
||||
sum = 0
|
||||
return
|
||||
|
||||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
method newNum(num) public
|
||||
sum = sum + num
|
||||
window.add(num)
|
||||
if window.size() > period then do
|
||||
rmv = (Rexx window.remove())
|
||||
sum = sum - rmv
|
||||
end
|
||||
return
|
||||
|
||||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
method getAvg() public returns Rexx
|
||||
if window.isEmpty() then do
|
||||
avg = 0
|
||||
end
|
||||
else do
|
||||
avg = sum / window.size()
|
||||
end
|
||||
return avg
|
||||
|
||||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
method run_samples(args = String[]) public static
|
||||
testData = [Rexx 1, 2, 3, 4, 5, 5, 4, 3, 2, 1]
|
||||
windowSizes = [Rexx 3, 5]
|
||||
loop windSize over windowSizes
|
||||
ma = RAvgSimpleMoving(windSize)
|
||||
loop xVal over testData
|
||||
ma.newNum(xVal)
|
||||
say 'Next number =' xVal.right(5)', SMA =' ma.getAvg().format(10, 9)
|
||||
end xVal
|
||||
say
|
||||
end windSize
|
||||
|
||||
return
|
||||
|
||||
-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
method main(args = String[]) public static
|
||||
run_samples(args)
|
||||
return
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
import deques
|
||||
|
||||
proc simplemovingaverage(period: int): auto =
|
||||
assert period > 0
|
||||
|
||||
var
|
||||
summ, n = 0.0
|
||||
values: Deque[float]
|
||||
for i in 1..period:
|
||||
values.addLast(0)
|
||||
|
||||
proc sma(x: float): float =
|
||||
values.addLast(x)
|
||||
summ += x - values.popFirst()
|
||||
n = min(n+1, float(period))
|
||||
result = summ / n
|
||||
|
||||
return sma
|
||||
|
||||
var sma = simplemovingaverage(3)
|
||||
for i in 1..5: echo sma(float(i))
|
||||
for i in countdown(5,1): echo sma(float(i))
|
||||
|
||||
echo ""
|
||||
|
||||
var sma2 = simplemovingaverage(5)
|
||||
for i in 1..5: echo sma2(float(i))
|
||||
for i in countdown(5,1): echo sma2(float(i))
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
let sma (n, s, q) x =
|
||||
let l = Queue.length q and s = s +. x in
|
||||
Queue.push x q;
|
||||
if l < n then
|
||||
(n, s, q), s /. float (l + 1)
|
||||
else (
|
||||
let s = s -. Queue.pop q in
|
||||
(n, s, q), s /. float l
|
||||
)
|
||||
|
||||
let _ =
|
||||
let periodLst = [ 3; 5 ] in
|
||||
let series = [ 1.; 2.; 3.; 4.; 5.; 5.; 4.; 3.; 2.; 1. ] in
|
||||
|
||||
List.iter (fun d ->
|
||||
Printf.printf "SIMPLE MOVING AVERAGE: PERIOD = %d\n" d;
|
||||
ignore (
|
||||
List.fold_left (fun o x ->
|
||||
let o, m = sma o x in
|
||||
Printf.printf "Next number = %-2g, SMA = %g\n" x m;
|
||||
o
|
||||
) (d, 0., Queue.create ()) series;
|
||||
);
|
||||
print_newline ();
|
||||
) periodLst
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
let sma_create period =
|
||||
let q = Queue.create ()
|
||||
and sum = ref 0.0 in
|
||||
fun x ->
|
||||
sum := !sum +. x;
|
||||
Queue.push x q;
|
||||
if Queue.length q > period then
|
||||
sum := !sum -. Queue.pop q;
|
||||
!sum /. float (Queue.length q)
|
||||
|
||||
let () =
|
||||
let periodLst = [ 3; 5 ] in
|
||||
let series = [ 1.; 2.; 3.; 4.; 5.; 5.; 4.; 3.; 2.; 1. ] in
|
||||
|
||||
List.iter (fun d ->
|
||||
Printf.printf "SIMPLE MOVING AVERAGE: PERIOD = %d\n" d;
|
||||
let sma = sma_create d in
|
||||
List.iter (fun x ->
|
||||
Printf.printf "Next number = %-2g, SMA = %g\n" x (sma x);
|
||||
) series;
|
||||
print_newline ();
|
||||
) periodLst
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
use Collection;
|
||||
|
||||
class MovingAverage {
|
||||
@window : FloatQueue;
|
||||
@period : Int;
|
||||
@sum : Float;
|
||||
|
||||
New(period : Int) {
|
||||
@window := FloatQueue->New();
|
||||
@period := period;
|
||||
}
|
||||
|
||||
method : NewNum(num : Float) ~ Nil {
|
||||
@sum += num;
|
||||
@window->Add(num);
|
||||
if(@window->Size() > @period) {
|
||||
@sum -= @window->Remove();
|
||||
};
|
||||
}
|
||||
|
||||
method : GetAvg() ~ Float {
|
||||
if(@window->IsEmpty()) {
|
||||
return 0; # technically the average is undefined
|
||||
};
|
||||
|
||||
return @sum / @window->Size();
|
||||
}
|
||||
|
||||
function : Main(args : String[]) ~ Nil {
|
||||
testData := [1.0, 2.0, 3.0, 4.0, 5.0, 5.0, 4.0, 3.0, 2.0, 1.0];
|
||||
windowSizes := [3.0, 5.0];
|
||||
|
||||
each(i : windowSizes) {
|
||||
windSize := windowSizes[i];
|
||||
ma := MovingAverage->New(windSize);
|
||||
each(j : testData) {
|
||||
x := testData[j];
|
||||
ma->NewNum(x);
|
||||
avg := ma->GetAvg();
|
||||
"Next number = {$x}, SMA = {$avg}"->PrintLine();
|
||||
};
|
||||
IO.Console->PrintLine();
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,94 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface MovingAverage : NSObject {
|
||||
unsigned int period;
|
||||
NSMutableArray *window;
|
||||
double sum;
|
||||
}
|
||||
- (instancetype)initWithPeriod:(unsigned int)thePeriod;
|
||||
@end
|
||||
|
||||
@implementation MovingAverage
|
||||
|
||||
// init with default period
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if(self) {
|
||||
period = 10;
|
||||
window = [[NSMutableArray alloc] init];
|
||||
sum = 0.0;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
// init with specified period
|
||||
- (instancetype)initWithPeriod:(unsigned int)thePeriod {
|
||||
self = [super init];
|
||||
if(self) {
|
||||
period = thePeriod;
|
||||
window = [[NSMutableArray alloc] init];
|
||||
sum = 0.0;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
// add a new number to the window
|
||||
- (void)add:(double)val {
|
||||
sum += val;
|
||||
[window addObject:@(val)];
|
||||
if([window count] > period) {
|
||||
NSNumber *n = window[0];
|
||||
sum -= [n doubleValue];
|
||||
[window removeObjectAtIndex:0];
|
||||
}
|
||||
}
|
||||
|
||||
// get the average value
|
||||
- (double)avg {
|
||||
if([window count] == 0) {
|
||||
return 0; // technically the average is undefined
|
||||
}
|
||||
return sum / [window count];
|
||||
}
|
||||
|
||||
// set the period, resizes current window
|
||||
- (void)setPeriod:(unsigned int)thePeriod {
|
||||
// make smaller?
|
||||
if(thePeriod < [window count]) {
|
||||
for(int i = 0; i < thePeriod; ++i) {
|
||||
NSNumber *n = window[0];
|
||||
sum -= [n doubleValue];
|
||||
[window removeObjectAtIndex:0];
|
||||
}
|
||||
}
|
||||
period = thePeriod;
|
||||
}
|
||||
|
||||
// get the period (window size)
|
||||
- (unsigned int)period {
|
||||
return period;
|
||||
}
|
||||
|
||||
// clear the window and current sum
|
||||
- (void)clear {
|
||||
[window removeAllObjects];
|
||||
sum = 0;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
int main (int argc, const char * argv[]) {
|
||||
@autoreleasepool {
|
||||
double testData[10] = {1,2,3,4,5,5,4,3,2,1};
|
||||
int periods[2] = {3,5};
|
||||
for(int i = 0; i < 2; ++i) {
|
||||
MovingAverage *ma = [[MovingAverage alloc] initWithPeriod:periods[i]];
|
||||
for(int j = 0; j < 10; ++j) {
|
||||
[ma add:testData[j]];
|
||||
NSLog(@"Next number = %f, SMA = %f", testData[j], [ma avg]);
|
||||
}
|
||||
NSLog(@"\n");
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
import: parallel
|
||||
|
||||
: createSMA(period)
|
||||
| ch |
|
||||
Channel new [ ] over send drop ->ch
|
||||
#[ ch receive + left(period) dup avg swap ch send drop ] ;
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
: 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 . ] ) ;
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
testdata = .array~of(1, 2, 3, 4, 5, 5, 4, 3, 2, 1)
|
||||
|
||||
-- run with different period sizes
|
||||
loop period over .array~of(3, 5)
|
||||
say "Period size =" period
|
||||
say
|
||||
movingaverage = .movingaverage~new(period)
|
||||
loop number over testdata
|
||||
average = movingaverage~addnumber(number)
|
||||
say " Next number =" number", moving average =" average
|
||||
end
|
||||
say
|
||||
end
|
||||
|
||||
::class movingaverage
|
||||
::method init
|
||||
expose period queue sum
|
||||
use strict arg period
|
||||
sum = 0
|
||||
-- the circular queue makes this easy
|
||||
queue = .circularqueue~new(period)
|
||||
|
||||
-- add a number to the average set
|
||||
::method addNumber
|
||||
expose queue sum
|
||||
use strict arg number
|
||||
sum += number
|
||||
-- add this to the queue
|
||||
old = queue~queue(number)
|
||||
-- if we pushed an element off the end of the queue,
|
||||
-- subtract this from our sum
|
||||
if old \= .nil then sum -= old
|
||||
-- and return the current item
|
||||
return sum / queue~items
|
||||
|
||||
-- extra method to retrieve current average
|
||||
::method average
|
||||
expose queue sum
|
||||
-- undefined really, but just return 0
|
||||
if queue~isempty then return 0
|
||||
-- return current queue
|
||||
return sum / queue~items
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
def max 1000
|
||||
|
||||
Class MovingAverage
|
||||
'==================
|
||||
|
||||
indexbase 1
|
||||
double average,invperiod,mdata[max]
|
||||
sys index,period
|
||||
|
||||
method Setup(double a,p)
|
||||
sys i
|
||||
Period=p
|
||||
invPeriod=1/p
|
||||
index=0
|
||||
average=a
|
||||
for i=1 to period
|
||||
mdata[i]=a
|
||||
next
|
||||
end method
|
||||
|
||||
method Data(double v) as double
|
||||
sys i
|
||||
index++
|
||||
if index>period then index=1 'recycle
|
||||
i=index+1 'for oldest data
|
||||
if i>period then i=1 'recycle
|
||||
mdata[index]=v
|
||||
average=average+invperiod*(v-mdata[i])
|
||||
end method
|
||||
|
||||
end class
|
||||
|
||||
'TEST
|
||||
'====
|
||||
|
||||
MovingAverage A
|
||||
|
||||
A.Setup 100,10 'initial value and period
|
||||
|
||||
A.data 50
|
||||
'...
|
||||
print A.average 'reult 95
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
declare
|
||||
|
||||
fun {CreateSMA Period}
|
||||
Xs = {NewCell nil}
|
||||
in
|
||||
fun {$ X}
|
||||
Xs := {List.take X|@Xs Period}
|
||||
|
||||
{FoldL @Xs Number.'+' 0.0}
|
||||
/
|
||||
{Int.toFloat {Min Period {Length @Xs}}}
|
||||
end
|
||||
end
|
||||
|
||||
in
|
||||
|
||||
for Period in [3 5] do
|
||||
SMA = {CreateSMA Period}
|
||||
in
|
||||
{System.showInfo "\nSTART PERIOD "#Period}
|
||||
for I in 1..5 do
|
||||
{System.showInfo " Number = "#I#" , SMA = "#{SMA {Int.toFloat I}}}
|
||||
end
|
||||
for I in 5..1;~1 do
|
||||
{System.showInfo " Number = "#I#" , SMA = "#{SMA {Int.toFloat I}}}
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
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
|
||||
};
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
SMA: procedure (N) returns (float byaddr);
|
||||
declare N fixed;
|
||||
declare A(*) fixed controlled,
|
||||
(p, q) fixed binary static initial (0);
|
||||
|
||||
if allocation(A) = 0 then signal error;
|
||||
|
||||
p = p + 1; if q < 20 then q = q + 1;
|
||||
if p > hbound(A, 1) then p = 1;
|
||||
A(p) = N;
|
||||
return (sum(float(A))/q);
|
||||
|
||||
I: ENTRY (Period);
|
||||
declare Period fixed binary;
|
||||
|
||||
if allocation(A) > 0 then FREE A;
|
||||
allocate A(Period);
|
||||
A = 0;
|
||||
p = 0;
|
||||
end SMA;
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
*process source attributes xref;
|
||||
mat: Proc Options(main);
|
||||
Dcl a(10) Dec Fixed(8,6);
|
||||
Dcl s Dec Fixed(10,8);
|
||||
Dcl n Bin Fixed(31) init(hbound(a)); /* number of items in the list. */
|
||||
Dcl p Bin Fixed(31) init(3); /* the 1st period */
|
||||
Dcl q Bin Fixed(31) init(5); /* the 2nd period */
|
||||
Dcl m Bin Fixed(31);
|
||||
Call i(a);
|
||||
|
||||
Put Edit(' SMA with SMA with',
|
||||
' number period 3 period 5',
|
||||
' -------- ---------- ----------')
|
||||
(Skip,a);
|
||||
Do m=1 To n;
|
||||
Put Edit(m,sma(p,m),sma(q,m))(Skip,f(5),2(f(13,6)));
|
||||
End;
|
||||
|
||||
i: Proc(a);
|
||||
Dcl a(*) Dec Fixed(8,6);
|
||||
Dcl (j,m) Bin Fixed(31);
|
||||
Do j=1 To hbound(a)/2;
|
||||
a(j)=j; /* ··· increasing values. */
|
||||
End;
|
||||
Do k=hbound(a)/2 To 1 By -1;
|
||||
a(j)=k; /* ··· decreasing values. */
|
||||
j+=1;
|
||||
End;
|
||||
End;
|
||||
|
||||
sma: Proc(p,j) Returns(Dec Fixed(8,6));
|
||||
Dcl s Dec fixed(8,6) Init(0);
|
||||
Dcl i Bin Fixed(31) Init(0);
|
||||
Dcl j Bin Fixed(31) Init((hbound(a)+1));
|
||||
Dcl (p,i,k,ka,kb) Bin Fixed(31);
|
||||
ka=max(1,j-p+1);
|
||||
kb=j+p;
|
||||
Do k=ka To kb While(k<=j);
|
||||
i+=1;
|
||||
s+=a(k)
|
||||
End;
|
||||
s=s/i+0.5e-6;
|
||||
Return(s);
|
||||
End;
|
||||
End;
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
program sma;
|
||||
type
|
||||
tsma = record
|
||||
smaValue : array of double;
|
||||
smaAverage,
|
||||
smaSumOld,
|
||||
smaSumNew,
|
||||
smaRezActLength : double;
|
||||
smaActLength,
|
||||
smaLength,
|
||||
smaPos :NativeInt;
|
||||
smaIsntFull: boolean;
|
||||
end;
|
||||
|
||||
procedure smaInit(var sma:tsma;p: NativeUint);
|
||||
Begin
|
||||
with sma do
|
||||
Begin
|
||||
setlength(smaValue,0);
|
||||
setlength(smaValue,p);
|
||||
smaLength:= p;
|
||||
smaActLength := 0;
|
||||
smaAverage:= 0.0;
|
||||
smaSumOld := 0.0;
|
||||
smaSumNew := 0.0;
|
||||
smaPos := p-1;
|
||||
smaIsntFull := true
|
||||
end;
|
||||
end;
|
||||
|
||||
function smaAddValue(var sma:tsma;v: double):double;
|
||||
Begin
|
||||
with sma do
|
||||
Begin
|
||||
IF smaIsntFull then
|
||||
Begin
|
||||
inc(smaActLength);
|
||||
smaRezActLength := 1/smaActLength;
|
||||
smaIsntFull := smaActLength < smaLength ;
|
||||
end;
|
||||
smaSumOld := smaSumOld+v-smaValue[smaPos];
|
||||
smaValue[smaPos] := v;
|
||||
smaSumNew := smaSumNew+v;
|
||||
|
||||
smaPos := smaPos-1;
|
||||
if smaPos < 0 then
|
||||
begin
|
||||
smaSumOld:= smaSumNew;
|
||||
smaSumNew:= 0.0;
|
||||
smaPos := smaLength-1;
|
||||
end;
|
||||
smaAverage := smaSumOld *smaRezActLength;
|
||||
smaAddValue:= smaAverage;
|
||||
end;
|
||||
end;
|
||||
|
||||
var
|
||||
sma3,sma5:tsma;
|
||||
i : LongInt;
|
||||
begin
|
||||
smaInit(sma3,3);
|
||||
smaInit(sma5,5);
|
||||
For i := 1 to 5 do
|
||||
Begin
|
||||
write('Inserting ',i,' into sma3 ',smaAddValue(sma3,i):0:4);
|
||||
writeln(' Inserting ',i,' into sma5 ',smaAddValue(sma5,i):0:4);
|
||||
end;
|
||||
For i := 5 downto 1 do
|
||||
Begin
|
||||
write('Inserting ',i,' into sma3 ',smaAddValue(sma3,i):0:4);
|
||||
writeln(' Inserting ',i,' into sma5 ',smaAddValue(sma5,i):0:4);
|
||||
end;
|
||||
//speed test
|
||||
smaInit(sma3,3);
|
||||
For i := 1 to 100000000 do
|
||||
smaAddValue(sma3,i);
|
||||
writeln('100''000''000 insertions ',sma3.smaAverage:0:4);
|
||||
end.
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
sub sma_generator {
|
||||
my $period = shift;
|
||||
my (@list, $sum);
|
||||
|
||||
return sub {
|
||||
my $number = shift;
|
||||
push @list, $number;
|
||||
$sum += $number;
|
||||
$sum -= shift @list if @list > $period;
|
||||
return $sum / @list;
|
||||
}
|
||||
}
|
||||
|
||||
# Usage:
|
||||
my $sma = sma_generator(3);
|
||||
for (1, 2, 3, 2, 7) {
|
||||
printf "append $_ --> sma = %.2f (with period 3)\n", $sma->($_);
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<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>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">sma_free</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">0</span>
|
||||
|
||||
<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>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">res</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">sma_free</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sma_free</span>
|
||||
<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>
|
||||
<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>
|
||||
<span style="color: #008080;">else</span>
|
||||
<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>
|
||||
<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>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">res</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<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>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">period</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">circnxt</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">history</span>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #000000;">circnxt</span> <span style="color: #0000FF;">+=</span> <span style="color: #000000;">1</span>
|
||||
<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>
|
||||
<span style="color: #000000;">circnxt</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</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;">3</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">circnxt</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;">val</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</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> <span style="color: #0000FF;">=</span> <span style="color: #000000;">history</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<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>
|
||||
<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>
|
||||
<span style="color: #000000;">sma_free</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">sidx</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">procedure</span>
|
||||
<!--
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
(phixonline)-->
|
||||
<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>
|
||||
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
|
||||
<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>
|
||||
<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>
|
||||
<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>
|
||||
<!--
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
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).
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
(de sma (@Len)
|
||||
(curry (@Len (Data)) (N)
|
||||
(push 'Data N)
|
||||
(and (nth Data @Len) (con @)) # Truncate
|
||||
(*/ (apply + Data) (length Data)) ) )
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
(def 'sma3 (sma 3))
|
||||
(def 'sma5 (sma 5))
|
||||
|
||||
(scl 2)
|
||||
(for N (1.0 2.0 3.0 4.0 5.0 5.0 4.0 3.0 2.0 1.0)
|
||||
(prinl
|
||||
(format N *Scl)
|
||||
" (sma3) "
|
||||
(format (sma3 N) *Scl)
|
||||
" (sma5) "
|
||||
(format (sma5 N) *Scl) ) )
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
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
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
#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)
|
||||
}
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
Procedure.d SMA(Number, Period=0)
|
||||
Static P
|
||||
Static NewList L()
|
||||
Protected Sum=0
|
||||
If Period<>0
|
||||
P=Period
|
||||
EndIf
|
||||
LastElement(L())
|
||||
AddElement(L())
|
||||
L()=Number
|
||||
While ListSize(L())>P
|
||||
FirstElement(L())
|
||||
DeleteElement(L(),1)
|
||||
Wend
|
||||
ForEach L()
|
||||
sum+L()
|
||||
Next
|
||||
ProcedureReturn sum/ListSize(L())
|
||||
EndProcedure
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue