Copyright (C) 1994, Digital Equipment Corp.
MODULE Stat;
IMPORT Wr, Fmt, Math, Thread;
PROCEDURE Init (VAR s: T) =
BEGIN
WITH z = s DO
z.num := 0.0d+0;
z.maximum := 0.0;
z.minimum := 0.0;
z.mean := 0.0d+0;
z.variance := 0.0d+0;
END
END Init;
PROCEDURE Accum (VAR s: T; x: REAL) =
VAR oldnum, tmp: LONGREAL;
BEGIN
WITH z = s DO
IF z.num = 0.0d+0 THEN
z.maximum := x;
z.minimum := x
ELSIF x > z.maximum THEN
z.maximum := x
ELSIF x < z.minimum THEN
z.minimum := x
END;
oldnum := z.num;
z.num := z.num + 1.0d+0;
tmp := FLOAT (x, LONGREAL) - z.mean;
z.mean := z.mean + tmp / z.num;
z.variance := (z.variance + tmp * tmp / z.num) * oldnum / z.num;
END;
END Accum;
PROCEDURE Combine (READONLY r, s: T): T =
VAR tmp: LONGREAL; t: T;
BEGIN
WITH z = t DO
z.maximum := MAX (r.maximum, s.maximum);
z.minimum := MIN (r.minimum, s.minimum);
z.num := r.num + s.num;
z.mean := (r.mean * r.num + s.mean * s.num) / z.num;
tmp := r.mean - s.mean;
z.variance := (r.variance * r.num + s.variance * s.num
+ tmp * tmp * r.num * s.num / z.num) / z.num;
END;
RETURN t
END Combine;
PROCEDURE Num (READONLY s: T): REAL =
BEGIN
RETURN FLOAT (s.num)
END Num;
PROCEDURE Max (READONLY s: T): REAL =
BEGIN
RETURN s.maximum
END Max;
PROCEDURE Min (READONLY s: T): REAL =
BEGIN
RETURN s.minimum
END Min;
PROCEDURE Mean (READONLY s: T): REAL =
BEGIN
RETURN FLOAT (s.mean)
END Mean;
PROCEDURE Var (READONLY s: T): REAL =
BEGIN
RETURN FLOAT (s.variance)
END Var;
PROCEDURE SDev (READONLY s: T): REAL =
BEGIN
IF s.num = 0.0d+0 THEN RETURN 0.0 END;
RETURN FLOAT (Math.sqrt (s.variance * s.num / (s.num - 1.0d+0)))
END SDev;
PROCEDURE RMS (READONLY s: T): REAL =
BEGIN
IF s.num = 0.0d+0 THEN
RETURN 0.0
ELSE
RETURN FLOAT (Math.sqrt (s.variance + s.mean * s.mean))
END
END RMS;
PROCEDURE Print (wr: Wr.T; READONLY s: T) RAISES {Wr.Failure, Thread.Alerted}=
BEGIN
WITH z = s DO
Wr.PutText (wr, "num = " & Fmt.Int (TRUNC (z.num)));
IF z.num > 0.0d+0 THEN
Wr.PutText (wr, " [ " & Fmt.Real (Min (s)) & " _ "
& Fmt.Real (Max (s)) & " ] mean = "
& Fmt.Real (Mean (s)));
IF z.num >= 2.0d+0 THEN
Wr.PutText (wr, " dev = " & Fmt.Real (SDev (s)))
END;
END;
END;
END Print;
BEGIN
END Stat.