Averages/Simple moving average: Difference between revisions

no edit summary
No edit summary
Line 2,486:
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
};</lang>
=={{header|Pascal}}==
{{works with|Free Pascal}}
Like in other implementations the sum of the last p values is only updated by subtracting the oldest value and addindg the new. To minimize rounding errors after p values the sum is corrected to the real sum.
<lang Pascal>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.</lang>
;output:
<pre>
time ./sma
Inserting 1 into sma3 1.0000 Inserting 1 into sma5 1.0000
Inserting 2 into sma3 1.5000 Inserting 2 into sma5 1.5000
Inserting 3 into sma3 2.0000 Inserting 3 into sma5 2.0000
Inserting 4 into sma3 3.0000 Inserting 4 into sma5 2.5000
Inserting 5 into sma3 4.0000 Inserting 5 into sma5 3.0000
Inserting 5 into sma3 4.6667 Inserting 5 into sma5 3.8000
Inserting 4 into sma3 4.6667 Inserting 4 into sma5 4.2000
Inserting 3 into sma3 4.0000 Inserting 3 into sma5 4.2000
Inserting 2 into sma3 3.0000 Inserting 2 into sma5 3.8000
Inserting 1 into sma3 2.0000 Inserting 1 into sma5 3.0000
100'000'000 insertions 99999999.0000
 
real 0m0.780s { 64-Bit }</pre>
=={{header|Perl}}==
 
Anonymous user