MODULE; RandomCombinedFast
Gnu CopyLefted.
Abstract: Pseudo-random number generator by Warren D. Smith.
IMPORT LongRealBasic AS R, LongRealTrans AS RT, RandomIteratedSquaring AS IterSqr, RandomSubtractiveFibo1 AS SubFibo1, RandomSubtractiveFibo2 AS SubFibo2, RandomMultiplicativeFibo AS MulFibo, Word, FloatMode; IMPORT RandomRep; <* UNUSED *> CONST Module = "RandomCombinedFast."; REVEAL T = TPublic BRANDED OBJECT subfibo1: SubFibo1.T; subfibo2: SubFibo2.T; mulfibo : MulFibo.T; OVERRIDES init := Init; generateWord := GenerateWord; generateReal := GenerateReal; END;* However, if your need for speed is so great that RandCombinedSlow will not do, try the routines below, which only combine two of the 5 generators in RandCombinedSlow, selected for high speed and high randomness. **************************************
PROCEDURE** Initializes all random number generators here. Quite slow. If fixed=FALSE (the default) will use the time as seed. If TRUE will use a particular fixed seed. ************************************************************GenerateWord (SELF: T; ): Word.T = BEGIN RETURN Word.Plus(SELF.subfibo2.engine(), SELF.mulfibo.engine()); END GenerateWord; PROCEDUREGenerateReal (SELF: T; ): R.T = <* FATAL FloatMode.Trap *> VAR x: R.T; BEGIN x := R.Scalb(R.Scalb(FLOAT(SELF.mulfibo.engine(), R.T), 6 - Word.Size) + FLOAT(SELF.mulfibo.engine(), R.T), -Word.Size); (** note, those multiplications were really just bit shifts. How * do I get the compiler to know that?? *) <* ASSERT -RT.Half <= x *> <* ASSERT x < 0.52D0 *> IF x < R.Zero THEN x := x + R.One; END; x := x - SELF.subfibo1.engine(); IF x < R.Zero THEN x := x + R.One; END; <* ASSERT x >= R.Zero *> <* ASSERT x < R.One *> RETURN x; END GenerateReal;
PROCEDUREInit (SELF: T; fixed: BOOLEAN := FALSE; ): T = VAR is := NEW(IterSqr.T).init(fixed); BEGIN SELF.subfibo1 := NEW(SubFibo1.T).init(is); SELF.subfibo2 := NEW(SubFibo2.T).init(is); SELF.mulfibo := NEW(MulFibo.T).init(is); (* rev 'em up by 60 calls to Uni01() *) FOR i := 0 TO 60 DO EVAL SELF.generateReal(); END; RETURN SELF; END Init; BEGIN END RandomCombinedFast.