This commit is contained in:
Ingy döt Net 2013-04-10 21:29:02 -07:00
parent 764da6cbbb
commit db842d013d
19005 changed files with 197040 additions and 7 deletions

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -0,0 +1 @@
lex =: 1 :'(a[n__a=.m#_.[a=.18!:3$~0)&(4 :''(+/%#)(#~1-128!:5)n__x=.1|.!.y n__x'')'

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -0,0 +1 @@
MA[x_List, r_] := Join[Table[Mean[x[[1;;y]]],{y,r-1}], MovingAverage[x,r]]

View file

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

View file

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