From 42fdcc5253208a51e0cea9141530f8e46b52c905 Mon Sep 17 00:00:00 2001 From: Wirawan Purwanto Date: Wed, 14 Aug 2013 15:29:26 -0400 Subject: [PATCH] * Added new module wpylib.math.random and its submodule (rng_lcg48). The LCG48 generator is primarily for testing algorithms involving random numbers. --- math/random/__init__.py | 13 +++ math/random/rng_lcg48.py | 166 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 179 insertions(+) create mode 100644 math/random/__init__.py create mode 100644 math/random/rng_lcg48.py diff --git a/math/random/__init__.py b/math/random/__init__.py new file mode 100644 index 0000000..d98b90a --- /dev/null +++ b/math/random/__init__.py @@ -0,0 +1,13 @@ +# +# wpylib.math.random module +# Created: 20130814 +# Wirawan Purwanto +# + +import numpy + +class rng_base(object): + """Bas class for random number generator.""" + +# Standard classes +from wpylib.math.random.rng_lcg48 import lcg48 diff --git a/math/random/rng_lcg48.py b/math/random/rng_lcg48.py new file mode 100644 index 0000000..a0f5324 --- /dev/null +++ b/math/random/rng_lcg48.py @@ -0,0 +1,166 @@ +# +# wpylib.math.random.rng_lcg48 module +# Created: 20130814 +# Wirawan Purwanto +# + +""" +wpylib.math.random.rng_lcg48 module +Implementation of 48-bit Linear Congruential pseudorandom number generator + +This RNG is used only for testing and regression purposes. + + +""" + +from wpylib.math.random import rng_base + +class lcg48(rng_base): + """Linear congruential pseudorandom number generator. + By default this implements the `rannyu' routine.""" + m = 34522712143931 # 11**13 + # This is "seed 1" in the legacy rannyu seed library. + L = 127 + n = 11863279 + div_two_48 = 2.0**(-48) + def __call__(self): + L_new = (self.m * self.L + self.n) & 0xFFFFFFFFFFFF + self.L = L_new + if L_new == 0: + return self.div_two_48 + else: + return L_new * self.div_two_48 + def update_seed(self, Ln): + if len(Ln) == 2: + (self.L, self.n) = (Ln[0], Ln[1]) + self.seed_index = None + elif len(Ln) == 3: + (self.seed_index, self.L, self.n) = (Ln[0], Ln[1], Ln[2]) + else: + raise TypeError, "Unsupported seed type." + def use_seed_lib(self, index): + self.m = 34522712143931 # 11**13 + self.update_seed(rannyu_seed_lib[index]) + +def mkint48(N): + """Generates a 48-bit number from four integers. + Used for encoding conversion for legacy rannyu library.""" + return N[3] + (N[2] << 12) + (N[1] << 24) + (N[0] << 36) + +def split48(value): + i4 = value & 0xFFF + value >>= 12 + i3 = value & 0xFFF + value >>= 12 + i2 = value & 0xFFF + value >>= 12 + i1 = value & 0xFFF + return (i1,i2,i3,i4) + + +rannyu_seed_lib = [ + (), # 0 is not used + (1, 127, 11863279), + (2, 127, 11863259), + (3, 127, 11863253), + (4, 127, 11863249), + (5, 127, 11863237), + (6, 127, 11863213), + (7, 152656382984915, 11863279), + (8, 152656382984915, 11863259), + (9, 152656382984915, 11863253), + (10, 152656382984915, 11863249), + (11, 152656382984915, 11863237), + (12, 152656382984915, 11863213), + (13, 127, 11863207), + (14, 127, 11863183), + (15, 152656382984915, 11863207), + (16, 152656382984915, 11863183), + (17, 152656382984915, 11863171), + (18, 152656382984915, 11863153), + (19, 152656382984915, 11863151), + (20, 152656382984915, 11863133), + (21, 152656382984915, 11863123), + (22, 152656382984915, 11863121), + (23, 152656382984915, 11863109), + (24, 152656382984915, 11863099), + (25, 127, 11863171), + (26, 127, 11863153), + (27, 127, 11863151), + (28, 127, 11863133), + (29, 127, 11863123), + (30, 127, 11863121), + (31, 127, 11863109), + (32, 127, 11863099), + (33, 152656382984915, 11863073), + (34, 127, 11863073), + (35, 152656382984915, 11863067), + (36, 127, 11863067), + (37, 152656382984915, 11863057), + (38, 127, 11863057), + (39, 152656382984915, 11863039), + (40, 127, 11863039), + (41, 152656382984915, 11863037), + (42, 127, 11863037), + (43, 127, 11863031), + (44, 127, 11863021), + (45, 127, 11862997), + (46, 127, 11862989), + (47, 127, 11862979), + (48, 127, 11862959), + (49, 127, 11862919), + (50, 127, 11862911), + (51, 127, 11862881), + (52, 127, 11862869), + (53, 127, 11862857), + (54, 127, 11862841), + (55, 127, 11862839), + (56, 127, 11862803), + (57, 127, 11862791), + (58, 127, 11862761), + (59, 127, 11862713), + (60, 127, 11862013), + (61, 127, 11862007), + (62, 127, 11861987), + (63, 127, 11861959), + (64, 127, 11861953), + (65, 127, 11861923), + (66, 127, 11861819), + (67, 127, 11861803), + (68, 127, 11861791), + (69, 127, 11861749), + (70, 127, 11861713), + (71, 127, 11861711), + (72, 127, 11861701), + (73, 152656382984915, 11863031), + (74, 152656382984915, 11863021), + (75, 152656382984915, 11862997), + (76, 152656382984915, 11862989), + (77, 152656382984915, 11862979), + (78, 152656382984915, 11862959), + (79, 152656382984915, 11862919), + (80, 152656382984915, 11862911), + (81, 152656382984915, 11862881), + (82, 152656382984915, 11862869), + (83, 152656382984915, 11862857), + (84, 152656382984915, 11862841), + (85, 152656382984915, 11862839), + (86, 152656382984915, 11862803), + (87, 152656382984915, 11862791), + (88, 152656382984915, 11862761), + (89, 152656382984915, 11862713), + (90, 152656382984915, 11862013), + (91, 152656382984915, 11862007), + (92, 152656382984915, 11861987), + (93, 152656382984915, 11861959), + (94, 152656382984915, 11861953), + (95, 152656382984915, 11861923), + (96, 152656382984915, 11861819), + (97, 152656382984915, 11861803), + (98, 152656382984915, 11861791), + (99, 152656382984915, 11861749), + (100, 152656382984915, 11861713), + (101, 152656382984915, 11861711), + (102, 152656382984915, 11861701), +] +