Averages/Simple moving average: Difference between revisions

m
reorder objeck and ocaml
m (→‎{{header|ooRexx}}: tiny correction)
m (reorder objeck and ocaml)
Line 1,709:
end
for v=1,30 do print(average(v)) end</lang>
 
=={{header|Objeck}}==
{{trans|Java}}
<lang objeck>
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();
};
}
}
</lang>
 
Output:
<pre>
Next number = 1.0, SMA = 1.0
Next number = 2.0, SMA = 1.500
Next number = 3.0, SMA = 2.0
Next number = 4.0, SMA = 3.0
Next number = 5.0, SMA = 4.0
Next number = 5.0, SMA = 4.667
Next number = 4.0, SMA = 4.667
Next number = 3.0, SMA = 4.0
Next number = 2.0, SMA = 3.0
Next number = 1.0, SMA = 2.0
 
Next number = 1.0, SMA = 1.0
Next number = 2.0, SMA = 1.500
Next number = 3.0, SMA = 2.0
Next number = 4.0, SMA = 2.500
Next number = 5.0, SMA = 3.0
Next number = 5.0, SMA = 3.800
Next number = 4.0, SMA = 4.200
Next number = 3.0, SMA = 4.200
Next number = 2.0, SMA = 3.800
Next number = 1.0, SMA = 3.0
</pre>
 
=={{header|OCaml}}==
<lang ocaml>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</lang>
 
Output:
<pre>
SIMPLE MOVING AVERAGE: PERIOD = 3
Next number = 1 , SMA = 1
Next number = 2 , SMA = 1.5
Next number = 3 , SMA = 2
Next number = 4 , SMA = 3
Next number = 5 , SMA = 4
Next number = 5 , SMA = 4.66667
Next number = 4 , SMA = 4.66667
Next number = 3 , SMA = 4
Next number = 2 , SMA = 3
Next number = 1 , SMA = 2
 
SIMPLE MOVING AVERAGE: PERIOD = 5
Next number = 1 , SMA = 1
Next number = 2 , SMA = 1.5
Next number = 3 , SMA = 2
Next number = 4 , SMA = 2.5
Next number = 5 , SMA = 3
Next number = 5 , SMA = 3.8
Next number = 4 , SMA = 4.2
Next number = 3 , SMA = 4.2
Next number = 2 , SMA = 3.8
Next number = 1 , SMA = 3
</pre>
 
More imperatively:
<lang ocaml>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</lang>
 
=={{header|Mathematica}}==
Line 2,005 ⟶ 1,852:
Next number = 1.0, SMA = 3.000000000
 
</pre>
 
=={{header|Objeck}}==
{{trans|Java}}
<lang objeck>
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();
};
}
}
</lang>
 
Output:
<pre>
Next number = 1.0, SMA = 1.0
Next number = 2.0, SMA = 1.500
Next number = 3.0, SMA = 2.0
Next number = 4.0, SMA = 3.0
Next number = 5.0, SMA = 4.0
Next number = 5.0, SMA = 4.667
Next number = 4.0, SMA = 4.667
Next number = 3.0, SMA = 4.0
Next number = 2.0, SMA = 3.0
Next number = 1.0, SMA = 2.0
 
Next number = 1.0, SMA = 1.0
Next number = 2.0, SMA = 1.500
Next number = 3.0, SMA = 2.0
Next number = 4.0, SMA = 2.500
Next number = 5.0, SMA = 3.0
Next number = 5.0, SMA = 3.800
Next number = 4.0, SMA = 4.200
Next number = 3.0, SMA = 4.200
Next number = 2.0, SMA = 3.800
Next number = 1.0, SMA = 3.0
</pre>
 
Line 2,135 ⟶ 2,057:
 
</pre>
 
=={{header|OCaml}}==
<lang ocaml>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</lang>
 
Output:
<pre>
SIMPLE MOVING AVERAGE: PERIOD = 3
Next number = 1 , SMA = 1
Next number = 2 , SMA = 1.5
Next number = 3 , SMA = 2
Next number = 4 , SMA = 3
Next number = 5 , SMA = 4
Next number = 5 , SMA = 4.66667
Next number = 4 , SMA = 4.66667
Next number = 3 , SMA = 4
Next number = 2 , SMA = 3
Next number = 1 , SMA = 2
 
SIMPLE MOVING AVERAGE: PERIOD = 5
Next number = 1 , SMA = 1
Next number = 2 , SMA = 1.5
Next number = 3 , SMA = 2
Next number = 4 , SMA = 2.5
Next number = 5 , SMA = 3
Next number = 5 , SMA = 3.8
Next number = 4 , SMA = 4.2
Next number = 3 , SMA = 4.2
Next number = 2 , SMA = 3.8
Next number = 1 , SMA = 3
</pre>
 
More imperatively:
<lang ocaml>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</lang>
 
=={{header|ooRexx}}==
Anonymous user