ðãSyntax10.Scn.FntSyntax10b.Scn.Fnt 9õÿÿÿ`=ðIStampElemsAlloc17 Mar 96& ! ÿÿÿÿ€8ÀÔFoldElemsNewÿÿÿÿ€8ÀÔÈÿÿÿ€8ÀÔ$Syntax10b.Scn.FntInteger distributions !ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔ$ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔ"ÿÿÿÿ€8ÀÔ"ÿÿÿÿ€8ÀÔ !ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔ#ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔ  ÿÿÿÿ€8ÀÔ4ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔËÿÿÿ€8ÀÔ$Syntax10b.Scn.FntReal distributions ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔ  ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔ ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔ ÿÿÿÿ€8ÀÔ0ÿÿÿÿ€8ÀÔÉÿÿÿ€8ÀÔ$Syntax10b.Scn.FntRandomize and Random  ÿÿÿÿ€8ÀÔ)ÿÿÿÿ€8ÀÔ ÿÿÿÿ€8ÀÔÛÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔÑÿÿÿ€8ÀÔ$Syntax10b.Scn.Fnt Distribution ÿÿÿÿ€8ÀÔ(ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔÔÿÿÿ€8ÀÔ$Syntax10b.Scn.Fnt RealDistr  ÿÿÿÿ€8ÀÔ/ÿÿÿÿ€8ÀÔ"¹ÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt%%abstract method, must be overridden%ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔÒÿÿÿ€8ÀÔ$Syntax10b.Scn.Fnt NormalDistr 3ÿÿÿÿ€8ÀÔSÿÿÿÿ€8ÀÔ$ÿÿÿÿ€8ÀÔ«ÿÿÿÿ€8ÀÔ$ ÿÿÿÿ€8ÀÔ>ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔÓÿÿÿ€8ÀÔ$Syntax10b.Scn.Fnt ExponDistr +ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔ"ÿÿÿÿ€8ÀÔ$ÿÿÿÿ€8ÀÔ#ÿÿÿÿ€8ÀÔ@ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔÑÿÿÿ€8ÀÔ$Syntax10b.Scn.Fnt IntegerDistr ÿÿÿÿ€8ÀÔ2ÿÿÿÿ€8ÀÔ%¹ÿÿÿ€8ÀÔ#Syntax10.Scn.Fnt%%abstract method, must be overridden%ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔÎÿÿÿ€8ÀÔ$Syntax10b.Scn.FntIntUniformDistr 2ÿÿÿÿ€8ÀÔ§ÿÿÿÿ€8ÀÔ(ÿÿÿÿ€8ÀÔNÿÿÿÿ€8ÀÔ( ÿÿÿÿ€8ÀÔ‘ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔÐÿÿÿ€8ÀÔ$Syntax10b.Scn.Fnt BinomialDistr 6ÿÿÿÿ€8ÀÔHÿÿÿÿ€8ÀÔ&ÿÿÿÿ€8ÀÔ&ÿÿÿÿ€8ÀÔ&ÿÿÿÿ€8ÀÔŽÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔÑÿÿÿ€8ÀÔ$Syntax10b.Scn.Fnt PoissonDistr .ÿÿÿÿ€8ÀÔGÿÿÿÿ€8ÀÔ%ÿÿÿÿ€8ÀÔÕÿÿÿÿ€8ÀÔ% ÿÿÿÿ€8ÀÔ*ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔÏÿÿÿ€8ÀÔ$Syntax10b.Scn.FntGeometricDistr )ÿÿÿÿ€8ÀÔ?ÿÿÿÿ€8ÀÔ'ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔ'ÿÿÿÿ€8ÀÔ_ÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔÒÿÿÿ€8ÀÔ$Syntax10b.Scn.Fnt PascalDistr Fÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔ$%ÿÿÿÿ€8ÀÔJÿÿÿÿ€8ÀÔ$ÿÿÿÿ€8ÀÔèÿÿÿÿ€8ÀÔÿÿÿÿ€8ÀÔhMODULE Statistics; (* Christoph Steindl, CS, steindl@ssw.uni-linz.ac.at,  *) IMPORT Out, Oberon, MathL; TYPE Distribution* = POINTER TO DistributionDesc; DistributionDesc* = RECORD END; IntegerDistr* = POINTER TO IntegerDistrDesc; IntegerDistrDesc* = RECORD (DistributionDesc) END; IntUniformDistr* = POINTER TO IntUniformDistrDesc; IntUniformDistrDesc* = RECORD (IntegerDistrDesc) min, max: LONGINT END; BinomialDistr* = POINTER TO BinomialDistrDesc; BinomialDistrDesc* = RECORD (IntegerDistrDesc) n: LONGINT; p: LONGREAL END; PoissonDistr* = POINTER TO PoissonDistrDesc; PoissonDistrDesc* = RECORD (IntegerDistrDesc) lambda: LONGREAL; END; GeometricDistr* = POINTER TO GeometricDistrDesc; GeometricDistrDesc* = RECORD (IntegerDistrDesc) p: LONGREAL END; PascalDistr* = POINTER TO PascalDistrDesc; PascalDistrDesc* = RECORD (IntegerDistrDesc) geometricVar: LONGINT; nofElems: LONGREAL END;  RealDistr* = POINTER TO RealDistrDesc; RealDistrDesc* = RECORD (DistributionDesc) END; NormalDistr* = POINTER TO NormalDistrDesc; NormalDistrDesc* = RECORD (RealDistrDesc) stdDev, mean: LONGREAL END; ExponDistr* = POINTER TO ExponDistrDesc; ExponDistrDesc* = RECORD (RealDistrDesc) mean: LONGREAL END; VAR z: LONGINT; PROCEDURE DisplayError* (s: ARRAY OF CHAR); BEGIN Out.Ln; Out.String(s) END DisplayError;  PROCEDURE Randomize*; BEGIN z := Oberon.Time() END Randomize;  PROCEDURE Random* (): LONGREAL; CONST A = 16807; M = 2147483647; Q = M DIV A; R = M MOD A; VAR gamma: LONGINT; BEGIN gamma := A * (z MOD Q) - R * (z DIV Q); IF gamma > 0 THEN z := gamma ELSE z := gamma + M END ; RETURN z * (1.0 / M) END Random;   PROCEDURE InitDistribution* (VAR d: DistributionDesc); BEGIN Randomize END InitDistribution;   PROCEDURE InitRealDistr* (VAR d: RealDistrDesc); BEGIN InitDistribution(d) END InitRealDistr;  PROCEDURE (VAR d: RealDistrDesc) GetRandomValue* (): LONGREAL; BEGIN HALT(34) END GetRandomValue;   PROCEDURE InitNormalDistr* (VAR d: NormalDistrDesc; stdDev, mean: LONGREAL); BEGIN InitRealDistr(d); d.stdDev := stdDev; d.mean := mean END InitNormalDistr;  PROCEDURE (VAR d: NormalDistrDesc) GetRandomValue* (): LONGREAL; VAR i: INTEGER; retval: LONGREAL; BEGIN retval := 0; FOR i := 1 TO 12 DO retval := retval + Random() END; RETURN d.mean + d.stdDev * (retval - 6) END GetRandomValue;  PROCEDURE (VAR d: NormalDistrDesc) SetStdDevMean* (stdDev, mean: LONGREAL); BEGIN d.stdDev := stdDev; d.mean := mean END SetStdDevMean;   PROCEDURE InitExponDistr* (VAR d: ExponDistrDesc; mean: LONGREAL); BEGIN END InitExponDistr;  PROCEDURE (VAR d: ExponDistrDesc) SetMean* (mean: LONGREAL); BEGIN d.mean := mean END SetMean;  PROCEDURE (VAR d: ExponDistrDesc) GetRandomValue* (): LONGREAL; BEGIN RETURN -d.mean * MathL.ln(Random()) END GetRandomValue;   PROCEDURE InitIntegerDistr* (VAR d: IntegerDistrDesc); BEGIN InitDistribution(d) END InitIntegerDistr;  PROCEDURE (VAR d: IntegerDistrDesc) GetRandomValue* (): LONGINT; BEGIN HALT(33) END GetRandomValue;   PROCEDURE InitIntUniformDistr* (VAR d: IntUniformDistrDesc; min, max: LONGINT); BEGIN InitIntegerDistr(d); IF min <= max THEN d.min := min; d.max := max ELSE DisplayError("InitIntUniformDistr: min must be <= max") END END InitIntUniformDistr;  PROCEDURE (VAR d: IntUniformDistrDesc) GetRandomValue* (): LONGINT; BEGIN RETURN ENTIER(d.min + (d.max - d.min) * Random()) END GetRandomValue;  PROCEDURE (VAR d: IntUniformDistrDesc) SetMinMax* (min, max: LONGINT); BEGIN IF min <= max THEN d.min := min; d.max := max ELSE DisplayError("IntUniformDistrDesc.SetMinMax: min must be <= max") END END SetMinMax;   PROCEDURE InitBinomialDistr* (VAR d: BinomialDistrDesc; n: LONGINT; p: LONGREAL); BEGIN InitIntegerDistr(d); d.p := p; d.n := n END InitBinomialDistr;  PROCEDURE (VAR d: BinomialDistrDesc) SetNP* (n: LONGINT; p: LONGREAL); BEGIN d.n := n; d.p := p END SetNP;  PROCEDURE (VAR d: BinomialDistrDesc) GetRandomValue* (): LONGINT; VAR realRetval, expect: LONGREAL; retval, i: LONGINT; found: BOOLEAN; normalValue: NormalDistr; BEGIN IF d.n < 25 THEN (* direct calculation for small n *) retval := 1; i := i; WHILE i <= d.n DO IF (Random() - d.p) <= 0 THEN INC(retval) ELSE RETURN retval END; INC(i) END ELSE (* approximation for greater n with normal distribution *) expect := d.n * d.p; NEW(normalValue); InitNormalDistr(normalValue^, 0, 1); REPEAT realRetval := normalValue.GetRandomValue(); retval := ENTIER(realRetval * MathL.sqrt(expect * (1 - d.p)) + expect + 0.5) UNTIL (retval > 0) & (retval < d.n); RETURN retval END; END GetRandomValue;   PROCEDURE InitPoissonDistr* (VAR d: PoissonDistrDesc; lambda: LONGREAL); BEGIN InitIntegerDistr(d); d.lambda := lambda END InitPoissonDistr;  PROCEDURE (VAR d: PoissonDistrDesc) GetRandomValue* (): LONGINT; VAR b, retval: LONGREAL; sum: LONGINT; BEGIN sum := 0; b := MathL.exp(-d.lambda); retval := Random(); WHILE (retval - b) >= 0 DO INC(sum); retval := retval * Random() END; RETURN sum END GetRandomValue;  PROCEDURE (VAR d: PoissonDistrDesc) SetLambda* (lambda: LONGREAL); BEGIN d.lambda := lambda END SetLambda;   PROCEDURE InitGeometricDistr* (VAR d: GeometricDistrDesc; p: LONGREAL); BEGIN InitIntegerDistr(d); d.p := p END InitGeometricDistr;  PROCEDURE (VAR d: GeometricDistrDesc) SetP* (p: LONGREAL); BEGIN d.p := p END SetP;  PROCEDURE (VAR d: GeometricDistrDesc) GetRandomValue* (): LONGINT; VAR retval: LONGINT; BEGIN IF (d.p >= 0.05) OR (d.p <= 0.95) THEN (* calculation for medium values of p *) RETURN ENTIER((MathL.ln(Random()) / MathL.ln(10)) / (MathL.ln(1 - d.p) / MathL.ln(10)) + 1) ELSE (* count method for extrem values of p *) retval := 1; WHILE Random() < d.p DO INC(retval) END; RETURN retval END END GetRandomValue;   PROCEDURE InitPascalDistr* (VAR d: PascalDistrDesc; geometricVar: LONGINT; nofElems: LONGREAL); BEGIN END InitPascalDistr;  PROCEDURE (VAR d: PascalDistrDesc) SetVarNofelems* (var: LONGINT; nofElems: LONGREAL); BEGIN d.geometricVar := var; d.nofElems := nofElems END SetVarNofelems;  PROCEDURE (VAR d: PascalDistrDesc) GetRandomValue* (): LONGINT; VAR retval: LONGREAL; i: LONGINT; BEGIN retval := 1; FOR i := 1 TO d.geometricVar DO retval := retval * Random() END; RETURN ENTIER((MathL.ln(retval) / MathL.ln(10)) / (MathL.ln(d.nofElems) / MathL.ln(10))) END GetRandomValue;   END Statistics.