Just another update

This commit is contained in:
Ingy döt Net 2015-02-20 00:35:01 -05:00
parent a25938f123
commit 00a190b0a6
6591 changed files with 94363 additions and 23227 deletions

View file

@ -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

View file

@ -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)))
)
);

View file

@ -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)

View file

@ -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));
}

View file

@ -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));
}

View file

@ -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).
].
].

View file

@ -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)
)

View file

@ -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 []

View file

@ -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))

View file

@ -0,0 +1,3 @@
SMA(N) = let buffer = Number[]
x -> (push!(buffer, x) ; mean(buffer[max(1,end-N+1):end]))
end

View file

@ -0,0 +1,6 @@
SMA(N, buffer = Number[]) =
x -> begin
push!(buffer, x)
if length(buffer) == N+1 shift!(buffer) end
mean(buffer)
end

View file

@ -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;

View file

@ -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