Just another update
This commit is contained in:
parent
a25938f123
commit
00a190b0a6
6591 changed files with 94363 additions and 23227 deletions
|
|
@ -4,7 +4,8 @@ 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.''
|
||||
|
||||
'''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().
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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,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)
|
||||
|
|
@ -1,11 +1,11 @@
|
|||
import std.stdio, std.traits, std.algorithm;
|
||||
|
||||
auto sma(T, int period)() {
|
||||
auto sma(T, int period)() pure nothrow @safe {
|
||||
T[period] data = 0;
|
||||
T sum = 0;
|
||||
int index, nFilled;
|
||||
|
||||
return (in T v) nothrow {
|
||||
return (in T v) nothrow @safe @nogc {
|
||||
sum += -data[index] + v;
|
||||
data[index] = v;
|
||||
index = (index + 1) % period;
|
||||
|
|
@ -19,6 +19,5 @@ void main() {
|
|||
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));
|
||||
writefln("Added %d, sma(3) = %f, sma(5) = %f", e, s3(e), s5(e));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ struct SMA(T, int period) {
|
|||
T sum = 0;
|
||||
int index, nFilled;
|
||||
|
||||
auto opCall(in T v) pure nothrow {
|
||||
auto opCall(in T v) pure nothrow @safe @nogc {
|
||||
sum += -data[index] + v;
|
||||
data[index] = v;
|
||||
index = (index + 1) % period;
|
||||
|
|
@ -19,6 +19,5 @@ void main() {
|
|||
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));
|
||||
writefln("Added %d, sma(3) = %f, sma(5) = %f", e, s3(e), s5(e));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,52 +3,53 @@
|
|||
#define system'collections.
|
||||
#define extensions.
|
||||
|
||||
#class SMAExtender
|
||||
#class SMA
|
||||
{
|
||||
#field thePeriod.
|
||||
#field theList.
|
||||
|
||||
#constructor new : aPeriod
|
||||
[
|
||||
thePeriod := aPeriod.
|
||||
theList := List new.
|
||||
]
|
||||
|
||||
#method add : aNumber
|
||||
#method append : aNumber
|
||||
[
|
||||
self += aNumber.
|
||||
theList += aNumber.
|
||||
|
||||
#var aCount := self length.
|
||||
#var aCount := theList length.
|
||||
^ aCount =>
|
||||
0 ? [ 0.0r ]
|
||||
! [
|
||||
(aCount > thePeriod)?
|
||||
[
|
||||
self remove &index:0.
|
||||
theList remove &index:0.
|
||||
|
||||
aCount := thePeriod.
|
||||
].
|
||||
|
||||
#var aSum := Summing new:(Real new:0) foreach:self.
|
||||
^ aSum / self length.
|
||||
#var aSum := Summing new:(Real new &int:0) foreach:theList.
|
||||
|
||||
^ aSum / aCount.
|
||||
].
|
||||
]
|
||||
}
|
||||
|
||||
#symbol sma = (:aPeriod) [ Extension(SMAExtender new:aPeriod, List new) ].
|
||||
|
||||
// --- Program ---
|
||||
|
||||
#symbol program =
|
||||
[
|
||||
#var SMA3 := sma:3.
|
||||
#var SMA5 := sma:5.
|
||||
#var SMA3 := SMA new:3.
|
||||
#var SMA5 := SMA new:5.
|
||||
|
||||
control from:1 &to:5 &do: i
|
||||
control forrange &int:1 &int:5 &do: (&int:i)
|
||||
[
|
||||
consoleEx writeLine:"sma3 + " :i :" = ": (SMA3 + i number).
|
||||
consoleEx writeLine:"sma5 + " :i :" = ": (SMA5 + i number).
|
||||
consoleEx writeLine:"sma3 + " :i :" = ": (SMA3 += i).
|
||||
consoleEx writeLine:"sma5 + " :i :" = ": (SMA5 += i).
|
||||
].
|
||||
|
||||
control from:5 &backTo:1 &do: i
|
||||
control forrange &int:5 &int:1 &do: (&int:i)
|
||||
[
|
||||
consoleEx writeLine:"sma3 + " :i :" = ": (SMA3 + i number).
|
||||
consoleEx writeLine:"sma5 + " :i :" = ": (SMA5 + i number).
|
||||
consoleEx writeLine:"sma3 + " :i :" = ": (SMA3 += i).
|
||||
consoleEx writeLine:"sma5 + " :i :" = ": (SMA5 += i).
|
||||
].
|
||||
].
|
||||
|
|
|
|||
|
|
@ -0,0 +1,26 @@
|
|||
import Control.Monad
|
||||
import Data.List
|
||||
import Data.IORef
|
||||
|
||||
mean :: Fractional a => [a] -> a
|
||||
mean xs = sum xs / (genericLength xs)
|
||||
|
||||
series = [1,2,3,4,5,5,4,3,2,1]
|
||||
|
||||
simple_moving_averager period = do
|
||||
numsRef <- newIORef []
|
||||
return (\x -> do
|
||||
nums <- readIORef numsRef
|
||||
let xs = take period (x:nums)
|
||||
writeIORef numsRef xs
|
||||
return $ mean xs
|
||||
)
|
||||
|
||||
main = do
|
||||
sma3 <- simple_moving_averager 3
|
||||
sma5 <- simple_moving_averager 5
|
||||
forM_ series (\n -> do
|
||||
mm3 <- sma3 n
|
||||
mm5 <- sma5 n
|
||||
putStrLn $ "Next number = " ++ (show n) ++ ", SMA_3 = " ++ (show mm3) ++ ", SMA_5 = " ++ (show mm5)
|
||||
)
|
||||
|
|
@ -0,0 +1,28 @@
|
|||
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 = putStrLn $ (show result)
|
||||
where
|
||||
(result, _) = runState demostrateSMA []
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
// single-sided
|
||||
Array.prototype.simpleSMA=function(N) {
|
||||
return this.map(function(x,i,v) {
|
||||
if(i<N-1) return NaN;
|
||||
return v.filter(function(x2,i2) { return i2<=i && i2>i-N; }).reduce(function(a,b){ return a+b; })/N;
|
||||
}); };
|
||||
|
||||
g=[1,2,3,4,5,8,5,4];
|
||||
console.log(g.simpleSMA(3))
|
||||
console.log(g.simpleSMA(5))
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
SMA(N) = let buffer = Number[]
|
||||
x -> (push!(buffer, x) ; mean(buffer[max(1,end-N+1):end]))
|
||||
end
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
SMA(N, buffer = Number[]) =
|
||||
x -> begin
|
||||
push!(buffer, x)
|
||||
if length(buffer) == N+1 shift!(buffer) end
|
||||
mean(buffer)
|
||||
end
|
||||
|
|
@ -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;
|
||||
|
|
@ -1,35 +1,24 @@
|
|||
/*REXX program is illustrate simple moving average. */
|
||||
arg p q n . /*get some arguments (maybe). */
|
||||
if p=='' then p=3 /*the 1st period (default: 3).*/
|
||||
if q=='' then q=5 /* " 2nd " " 5 */
|
||||
if n=='' then n=10 /*number of items in the list.*/
|
||||
a.=0
|
||||
do j=1 for n%2 /*build beginning of the list,*/
|
||||
a.j=j /* ... increasing values. */
|
||||
end /*j*/
|
||||
|
||||
do k=n%2 to 1 by -1 /* ... decreasing values. */
|
||||
a.j=k
|
||||
j=j+1
|
||||
end /*k*/
|
||||
|
||||
do i=1 for n /*show an indented item list. */
|
||||
say left('',60) 'item' right(i,3)'='right(a.i,3)
|
||||
end /*i*/
|
||||
do m=1 for n /*OK the, let's start the SMA.*/
|
||||
smaP=sma(p,m) /*simple moving average for P.*/
|
||||
smaQ=sma(q,m) /* " " " " Q.*/
|
||||
|
||||
/*show 2 nicely formated SMAs.*/
|
||||
say 'm='right(m,3), /*show where we're at in list.*/
|
||||
" sma("p')='left(sma(p,m),11), /*show nicely aligned sma P. */
|
||||
" sma("q')='left(sma(q,m),11) /* " " " " Q. */
|
||||
end /*m*/
|
||||
exit
|
||||
/*────────────────────────────────────────SMA subroutine────────────────*/
|
||||
sma: procedure expose A.; arg p,j; s=0; i=0
|
||||
do k=max(1,j-p+1) to j+p for p while k<=j
|
||||
i=i+1
|
||||
s=s+a.k
|
||||
end
|
||||
/*REXX program illustrates simple moving average using a simple list. */
|
||||
parse arg p q n . /*get some arguments (maybe). */
|
||||
if p=='' then p=3 /*the 1st period (default: 3).*/
|
||||
if q=='' then q=5 /* " 2nd " " 5 */
|
||||
if n=='' then n=10 /*number of items in the list.*/
|
||||
@.=0 /*define stemmed array, init 0*/
|
||||
/*──────────────────────────────────────────build 1st half of the list. */
|
||||
do j=1 for n%2; @.j=j; end /* ··· increasing values.*/
|
||||
/*──────────────────────────────────────────build 2nd half of the list. */
|
||||
do k=n%2 to 1 by -1; @.j=k; j=j+1; end /* ··· decreasing values.*/
|
||||
/*──────────────────────────────────────────perform a simple moving avg.*/
|
||||
say ' ' " SMA with " ' SMA with '
|
||||
say ' number ' " period" p' ' ' period' q
|
||||
say ' ──────── ' "──────────" '──────────'
|
||||
do m=1 for n
|
||||
say center(@.m,10) left(sma(p,m),11) left(sma(q,m),11)
|
||||
end /*m*/ /* [↑] show simple moving avg.*/
|
||||
exit /*stick a fork in it, we're done.*/
|
||||
/*──────────────────────────────────SMA subroutine──────────────────────*/
|
||||
sma: procedure expose @.; parse arg p,j; s=0; i=0
|
||||
do k=max(1,j-p+1) to j+p for p while k<=j; i=i+1
|
||||
s=s+@.k
|
||||
end /*k*/
|
||||
return s/i
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue